home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1191 / 1191.xpi / chrome / reminderfox.jar / content / reminderfox / addReminderDialog.js < prev    next >
Text File  |  2010-01-19  |  233KB  |  6,785 lines

  1. const g_reminderFoxBundle = document.getElementById("reminderFox-bundle");  
  2.  
  3. const REPEAT_LABEL_NONE =    g_reminderFoxBundle.getString("rf.add.columns.repeat.none");
  4. const REPEAT_LABEL_YEARLY =    g_reminderFoxBundle.getString("rf.add.columns.repeat.yearly");
  5. const REPEAT_LABEL_YEARLY_DAY =    g_reminderFoxBundle.getString("rf.add.columns.repeat.yearlyDay");
  6. const REPEAT_LABEL_MONTHLY =    g_reminderFoxBundle.getString("rf.add.columns.repeat.monthly");
  7. const REPEAT_LABEL_MONTHLY_DAY =    g_reminderFoxBundle.getString("rf.add.columns.repeat.monthlyDay");
  8. const REPEAT_LABEL_WEEKLY =    g_reminderFoxBundle.getString("rf.add.columns.repeat.weekly");
  9. const REPEAT_LABEL_DAILY =    g_reminderFoxBundle.getString("rf.add.columns.repeat.daily");
  10.  
  11.  
  12. const REMINDER_FOX_TIME_ALL_DAY_LABEL = g_reminderFoxBundle.getString("rf.add.time.allday");
  13.  
  14. const REMINDER_FOX_AM =    g_reminderFoxBundle.getString("rf.add.time.AM");
  15. const REMINDER_FOX_PM =    g_reminderFoxBundle.getString("rf.add.time.PM");
  16. const REMINDER_FOX_TIME_DELIMITER=g_reminderFoxBundle.getString( "rf.add.time.delimiter");
  17.  
  18.  
  19. // constants 
  20. const REMINDER_ID_REF = "idRef";
  21. const REMINDER_DATE_REF = "dateRef";
  22.  
  23. var g_modified = false;
  24.  
  25. var selectCalendarSync = false;
  26. var calendarReminderArray = null; // new Array(12);
  27. var calendarTodoArray = null;
  28.  
  29. var lastSearchString = null;
  30.  
  31. var reminderFox_subscribedCalendars = { };
  32.  
  33. var useDefaultDate = true;
  34. var dateVariableString = "";
  35.  
  36. var REPEAT_PREVIOUS_OCCURRENCES;
  37. var REPEAT_UPCOMING_OCCURRENCES;
  38.  
  39. var SHOW_ALL_REMINDERS = false;
  40. var HIDE_ALL_REMINDERS = false;
  41. var HIDE_COMPLETED_ITEMS = false;
  42. var reminderFoxTabDirtied = false;
  43.  
  44. var reminderFox_highlightTodayPreference = true;
  45.  
  46. var listSortMap = null;
  47.  
  48. // searchbar
  49. var searchBarWaitTime = null;  
  50. const SEARCHBAR_WAIT_DELAY = 600;
  51.  
  52. const searchItems     = ["summary",            "categories",        "notes", "location"];
  53. const rmColumnLabels    = ["descColLabel",        "catColLabel",        "notesColLabel"];
  54. const tdColumnLabels    = ["todoDescColLabel",    "todocatColLabel",    "todoNotesColLabel"];
  55.  
  56. //gW_focus
  57. function selectFocus(element) {
  58.     var str ="";
  59.     if ((element == null)) {
  60.         isReminderTabSelected() ? 
  61.                 document.getElementById("addReminderButton").focus()        
  62.             :    document.getElementById("addTodoButton").focus();
  63.     } else {
  64.        document.getElementById(element).focus(); 
  65.     }
  66. }
  67.  
  68. var lastRmSearchText ="";
  69. var lastTodoSearchText = "";
  70. var lastTodoTab = "";
  71. var currentRmSearchItemValue = 0;
  72. var currentTodoSearchItemValue=0;
  73.     
  74. function rmCheckMenuItem (menuNo){
  75. /*    ----------------------------- sets the selected menu item  by menuNo
  76. */
  77.     var menuItems = document.getElementById('quick-search-menupopup')
  78.         .getElementsByAttribute('value', '*');
  79.         
  80.     if (menuItems.length > 0)  {    
  81.         for (var i=1; i< menuItems.length; i++) {
  82.             menuItems[i].removeAttribute('checked');
  83.         }      
  84.     }      
  85.     menuItems[menuNo].setAttribute('checked', 'true');  
  86.  
  87.     var cLabel = document.getElementById('rmSearchText')
  88.     cLabel.value =     menuItems[menuNo].getAttribute('label');
  89.     
  90.     if ( isReminderTabSelected() ) {
  91.         currentRmSearchItemValue = menuNo;
  92.     }
  93.     else {
  94.         currentTodoSearchItemValue = menuNo;
  95.     }
  96.     //if ( isListFiltered() ) {  // always want to clear headers
  97.         rmHighlightHeader(menuNo);
  98.     //}
  99. }
  100.  
  101. function rmHighlightHeader(menuNo) {
  102.     /*  ------  'highligth the List-Column-Header'  ------ */    
  103.     if ( isReminderTabSelected() ) {
  104.         for (var i=0; i < rmColumnLabels.length; i++) {
  105.             var colLabel = document.getElementById(rmColumnLabels[i]);
  106.             if ( colLabel != null ) {
  107.                 colLabel.setAttribute( "style", "color:black; font-weight:normal");
  108.             }
  109.         }
  110.         if ( isListFiltered() ) {
  111.             var colLabel = document.getElementById(rmColumnLabels[menuNo])    
  112.             if ( colLabel != null ) {
  113.                 colLabel.setAttribute( "style", "color:blue; font-weight:bold");
  114.             }
  115.         }
  116.     }
  117.     else {        
  118.         for (var i=0; i < tdColumnLabels.length; i++) {
  119.             var colLabel = document.getElementById(tdColumnLabels[i])    ;
  120.             if ( colLabel != null ) {
  121.                 colLabel.setAttribute( "style", "color:black; font-weight:normal");
  122.             }
  123.         }
  124.         if ( isListFiltered() ) { 
  125.             var colLabel = document.getElementById(tdColumnLabels[menuNo]);
  126.             if ( colLabel != null ) {
  127.                 colLabel.setAttribute( "style", "color:blue; font-weight:bold");
  128.             }
  129.         }
  130.     }
  131. }
  132.  
  133. function rmOnInputQSearch(event) {
  134. /*    -------------------------- this is called with every Input action 
  135. */
  136.     event.style.color="blue";  
  137. }        
  138.  
  139.  
  140. /**
  141.  * The quicksearch response is split between onSearchKeyDown and onSearchKeyUp because this logic
  142.  * is tied to a timed function that sets the focus on the quicksearch bar after a period of time.
  143.  * This split is required for Japanese input using Input Method Editor(IME), where they enter some characters and 
  144.  * then need to select the converted Japanese text from the IME.  If the quicksearch textbox steals the focus 
  145.  * before that is completed, it screws up the input conversion.  As such, we put the logic in the onKeyUp event
  146.  * instead, which is only called after the IME is finished.  
  147.  */
  148. function rmOnSearchKeyPress(event)    {
  149.     if (event.keyCode==9) {
  150.          return;        /* break the focus */
  151.     }
  152.     
  153.     var qs_button = document.getElementById('quick-search-clearbutton');
  154.     if (qs_button != null) {
  155.         qs_button.setAttribute('clearButtonShown', true);
  156.     }
  157. }
  158.  
  159.  
  160. function rmOnSearchKeyUp(event) {
  161. /*    -------------------------    read Char in with delay to catch last one
  162. */
  163.     if ( event.keyCode == 13) { // if 'return' pressed, filter the view immediately
  164.         var desc = document.getElementById("rmSearchText");
  165.         if ( isReminderTabSelected() ) {
  166.             lastRmSearchText =  desc.value;                
  167.             rmHighlightHeader(currentRmSearchItemValue);            
  168.         }
  169.         else {
  170.             lastTodoSearchText =  desc.value;            
  171.             rmHighlightHeader(currentTodoSearchItemValue);    
  172.             
  173.             var tabList = document.getElementById("tabList");    
  174.             var tab =    tabList.selectedItem;
  175.             lastTodoTab = tab.getAttribute( "label");
  176.         }
  177.         searchBarWaitTime = null;
  178.         refillLists();  
  179.         desc.focus();      
  180.     }
  181.     else {
  182.         searchBarWaitTime = new Date().getTime() + SEARCHBAR_WAIT_DELAY;
  183.         setTimeout("rmOnSearchInput();", SEARCHBAR_WAIT_DELAY);    
  184.     }
  185. }
  186.  
  187. function isListFiltered() {
  188.     if ( isReminderTabSelected() ) {
  189.         if (lastRmSearchText != "") { 
  190.             return true;
  191.         }
  192.     }
  193.     else {
  194.         if (lastTodoSearchText != "") { 
  195.             return true;
  196.         }
  197.     }
  198.     return false;
  199. }
  200.  
  201. function rmOnSearchFocus(event) {
  202.     if ( !isListFiltered()) {
  203.         var desc = document.getElementById("rmSearchText");
  204.         desc.value = "";        /*  erase the descriptive text */    
  205.     }
  206. }
  207.  
  208. function rmOnSearchInput() {
  209. /*    -----------------    update Reminder and ToDo lists  & get focus back
  210. */
  211.     if ( searchBarWaitTime != null ) {
  212.         var currentTime = new Date().getTime();
  213.         // only update the search view if enough time has passed since the last keystroke
  214.         if ( (currentTime + 15)  > searchBarWaitTime ) {    
  215.             
  216.             var desc = document.getElementById("rmSearchText");
  217.             if ( isReminderTabSelected() ) {
  218.                 lastRmSearchText =  desc.value;        
  219.                 
  220.                 if ( lastRmSearchText == "" ) {
  221.                     document.getElementById('quick-search-clearbutton').setAttribute('clearButtonShown', false);
  222.                 }                
  223.                 rmHighlightHeader(currentRmSearchItemValue);            
  224.             
  225.             }
  226.             else {
  227.                 lastTodoSearchText =  desc.value;            
  228.                 if ( lastTodoSearchText == "" ) {
  229.                     document.getElementById('quick-search-clearbutton').setAttribute('clearButtonShown', false);
  230.                 }            
  231.                 var tabList = document.getElementById("tabList");    
  232.                 var tab =    tabList.selectedItem;
  233.                 lastTodoTab = tab.getAttribute( "label")
  234.                 rmHighlightHeader(currentTodoSearchItemValue);            
  235.             }
  236.             
  237.             refillLists();  
  238.             var desc = document.getElementById("rmSearchText");
  239.             desc.focus();      
  240.         }
  241.     }
  242. }
  243.  
  244.     
  245. function rmOnBlueClearButton () {
  246. /*    -------------------------------------------- the Clear Button was hit 
  247. */
  248.     if ( isReminderTabSelected() ) {
  249.         lastRmSearchText = ""; 
  250.         rmCheckMenuItem(currentRmSearchItemValue); 
  251.     } else {
  252.         lastTodoSearchText = "";
  253.         rmCheckMenuItem(currentTodoSearchItemValue);
  254.     }
  255.  
  256.     rmClearSearch(true);
  257. }
  258.  
  259. function rmChangeQuickSearchMode(aMenuItem)  {
  260. /*    -----------------------------------------------------
  261.     for current TAB remember 'menuItem' and clear input 
  262. */
  263.     var searchText = document.getElementById('rmSearchText')        
  264.     searchText.value = "";
  265.     
  266.     if ( isReminderTabSelected() ) {
  267.         lastRmSearchText = "";         
  268.     } else {
  269.         lastTodoSearchText = "";
  270.     }    
  271.     
  272.     rmCheckMenuItem(aMenuItem.value); 
  273.     rmClearSearch(true);
  274.     
  275.     // move focus out of the text field (so user has to refocus)
  276.     if ( isReminderTabSelected() ) {
  277.         selectNewReminderText();
  278.     }
  279.     else {
  280.         var desc = document.getElementById("addTodoButton");
  281.         desc.focus();     
  282.     }
  283. }
  284.  
  285. /**
  286.  *     reset menuItem and clear input
  287.  */    
  288. function rmInitQuickSearchPopup() {
  289. // -----------------------------------------------------
  290.     if ( isReminderTabSelected() ) {
  291.         rmCheckMenuItem(currentRmSearchItemValue);  
  292.     }
  293.     else {
  294.         rmCheckMenuItem(currentTodoSearchItemValue);  
  295.     }
  296.     
  297.     var rmSearchText = document.getElementById('rmSearchText')    
  298.     rmSearchText.style.color="grey";
  299.     
  300.     if ( isListFiltered() ) {
  301.         rmClearSearch();
  302.     }
  303.     
  304. }    
  305.  
  306.  
  307. function rmClearSearch(forceRefresh) {
  308.     /*  clear input text and the blue button and set to 'grey' text */
  309.     document.getElementById('quick-search-clearbutton').setAttribute('clearButtonShown', false);
  310.     
  311.     var rmSearchText = document.getElementById('rmSearchText')    
  312.     rmSearchText.style.color="grey";
  313.     
  314.     if ( forceRefresh || isListFiltered() ) {
  315.         /* update Reminder and ToDo lists  & get focus back */
  316.         refillLists(); 
  317.     }
  318. }
  319.  
  320.  
  321. function rmShowQSearch(isTabChange) {    
  322. /* ------- call with tab-change to change child and preselected values 
  323. */
  324.     var rmSearchText = document.getElementById('rmSearchText');
  325.     if ( isReminderTabSelected() ) { /* --- Reminders selected --- */    
  326.         if ( isTabChange ) {
  327.             var clonedQTPicker = rmSearchText.cloneNode( true );
  328.             rmSearchText.parentNode.removeChild( rmSearchText );
  329.             document.getElementById("rmSearchTextBox").appendChild( clonedQTPicker );
  330.         }
  331.     
  332.         /* ---- if previous ReminderSearch, rebuild  ---- */
  333.         if ( isListFiltered() ) { 
  334.             rmCheckMenuItem(currentRmSearchItemValue);         
  335.             document.getElementById('rmSearchText').value = lastRmSearchText ;
  336.             
  337.             clonedQTPicker.clearButtonShown = true;                        
  338.             clonedQTPicker.style.color="blue";
  339.             
  340.             if ( isTabChange ) { // only update list on tab change (not on initial load)
  341.                 /* update Reminder and ToDo lists  & get focus back */                
  342.                 refillLists(); 
  343.                 document.getElementById('rmSearchText').focus();                  
  344.             }
  345.         }        
  346.         else {  /*    no previous remembered values    */
  347.                 /*    init input field & parameters  */
  348.             rmInitQuickSearchPopup();
  349.         }        
  350.     }
  351.     else {  /* ---    Todos oder user-Lists selected     --- */
  352.         /*   load XUL new */
  353.         if ( isTabChange ) {
  354.             var clonedQTPicker = rmSearchText.cloneNode( true );
  355.             rmSearchText.parentNode.removeChild( rmSearchText );
  356.             document.getElementById("todoSearchTextBox").appendChild( clonedQTPicker );
  357.         }
  358.         
  359.         if ( isListFiltered() ) {                     
  360.             var tabList = document.getElementById("tabList");    
  361.             var tab =    tabList.selectedItem;
  362.             var currentTabName = tab.getAttribute( "label");
  363.             if ( lastTodoTab != "" && currentTabName != lastTodoTab ) { // tab has changed; clear everything
  364.                 rmOnBlueClearButton();  // clear this todo search info
  365.             }
  366.             else {
  367.                 rmCheckMenuItem(currentTodoSearchItemValue);             
  368.                 document.getElementById('rmSearchText').value = lastTodoSearchText ;
  369.             
  370.                 clonedQTPicker.clearButtonShown = true;                        
  371.                 clonedQTPicker.style.color="blue";            
  372.             }
  373.         }
  374.         else {            
  375.             rmInitQuickSearchPopup();
  376.         }
  377.     }
  378. }
  379.  
  380.  
  381.  
  382. function selectTab() {    
  383.     // give focus to the reminder/todo description when switching tabs
  384.     selectCalendarSync = false;
  385.     var tabList = document.getElementById("tabList");     
  386.     var tabIndex =    tabList.selectedIndex;
  387.     
  388.     var panels = document.getElementById("tabPanelID");    
  389.     
  390.     
  391.     var currentReminderPanel = document.getElementById("treeparent").parentNode;
  392.     var currentTodoPanel = document.getElementById("todoTreeparent").parentNode;
  393.     
  394.     if ( !isReminderTabSelected() ) {
  395.         if ( panels.childNodes[tabIndex] == currentTodoPanel ) { // we clicked on the same tab...
  396.             if ( reminderFoxTabDirtied ) {
  397.                 reminderFoxTabDirtied = false;
  398.                 removeAllListItems( false, true );
  399.                 fillList( false, true );
  400.             }
  401.         }
  402.         else {
  403.             // this is the active tab -  we want to move its contents to new tab                
  404.             // first remove all the tree children from old tab (clear its todo list; it will be repopulated with
  405.             // todos from new list)
  406.             var treeChildren = document.getElementById("todoTreechildren");
  407.             if ( treeChildren != null && treeChildren.childNodes.length > 0 ) {
  408.                      while (treeChildren.hasChildNodes()) {
  409.                          treeChildren.removeChild(treeChildren.firstChild);
  410.                      }        
  411.             }                    
  412.     
  413.             // now move all elements from old tab to new tab
  414.             var newPanel = panels.childNodes[tabIndex];
  415.             while (currentTodoPanel.hasChildNodes()) {
  416.                     var child =  currentTodoPanel.removeChild(currentTodoPanel.firstChild);
  417.                     newPanel.appendChild(child);                                
  418.                }    
  419.             // add new todos to the new tab's list
  420.             fillList( false, true );
  421.         }
  422.         
  423.         var desc = document.getElementById("addTodoButton");
  424.         desc.focus();    
  425.     }
  426.     else {
  427.         if ( isSubscribedCalendarTabSelected() ) {
  428.             var subscribedCalArr =    getSubscribedCalendars();
  429.             var tabList = document.getElementById("tabList");    
  430.             var tab =    tabList.selectedItem;
  431.             var tabIndex =    tabList.selectedIndex;
  432.             var index = tab.id.indexOf( ':' );        
  433.             var name = tab.id.substring( index +1 , tab.id.length );
  434.             var subscribedCal = subscribedCalArr[name];
  435.             if ( subscribedCal != null  && subscribedCal.length == 0 ) {
  436.                 subscribedCal = null;
  437.                 subscribedCalArr[name] = subscribedCal;
  438.             }
  439.             
  440.             
  441.             
  442.             document.getElementById("addReminderButton").setAttribute( "disabled", true );
  443.         }
  444.         else {
  445.                 document.getElementById("addReminderButton").removeAttribute( "disabled" );
  446.         }
  447.         if ( panels.childNodes[tabIndex] == currentReminderPanel ) { // we clicked on the same tab...
  448. //                if ( reminderFoxTabDirtied ) {
  449. //                    reminderFoxTabDirtied = false;
  450. //                    removeAllListItems( false, true );
  451. //                    fillList( false, true );
  452. //                }
  453.         }
  454.         else {
  455.             // clear status text 
  456.             rmFxCore.statusSet ("");
  457.             
  458.             calendarReminderArray = null;  // clear array (in case sorted)
  459.             
  460.             // this is the active tab -  we want to move its contents to new tab                
  461.             // first remove all the tree children from old tab (clear its todo list; it will be repopulated with
  462.             // todos from new list)
  463.             var treeChildren = document.getElementById("treechildren");
  464.             if ( treeChildren != null && treeChildren.childNodes.length > 0 ) {
  465.                  while (treeChildren.hasChildNodes()) {
  466.                      treeChildren.removeChild(treeChildren.firstChild);
  467.                  }        
  468.             }                    
  469.     
  470.             // now move all elements from old tab to new tab
  471.             var newPanel = panels.childNodes[tabIndex];
  472.             while (currentReminderPanel.hasChildNodes()) {
  473.                     var child =  currentReminderPanel.removeChild(currentReminderPanel.firstChild);
  474.                     newPanel.appendChild(child);                                
  475.                }    
  476.                               
  477.             // add new todos to the new tab's list
  478.             fillList( true, false );                            
  479.         }
  480.         selectNewReminderText();                    
  481.     }
  482.  
  483.     selectCalendarSync = true;   
  484.     // show calendar based on button state            
  485.     reminderFox_showCal();        
  486.     
  487.     oeDatePicker.redrawDays();
  488.     
  489.     rmFx_View.Clone(); 
  490.     
  491.     //  dynamically insert Quick-Search box 
  492.     rmShowQSearch(true);   //true= need to update 'fillList'    //gW_Search 
  493. }
  494.  
  495. function isReminderTabSelected() {
  496.     var remindersTab = document.getElementById("remindersTab");
  497.     if ( remindersTab == null || remindersTab.selected ) {
  498.         return true;
  499.     }
  500.     else {
  501.         if ( isSubscribedCalendarTabSelected()) {
  502.             return true;
  503.         }
  504.         else {
  505.             return false;
  506.         }
  507.     }    
  508. }
  509.  
  510. function isSubscribedCalendarTabSelected() {
  511.     var tabList = document.getElementById("tabList");    
  512.     var tab =    tabList.selectedItem;
  513.     var listName = tab.getAttribute( "label");
  514.     
  515.     var subscriptions = reminderFox_getSubscriptions();    
  516.     var url = subscriptions[listName];
  517.     if ( url != null && url.length > 0 ) {
  518.         return true;
  519.     }
  520.     else {
  521.         return false;
  522.     }    
  523. }
  524.  
  525. function reminderFox_removeListItems(listID) {
  526.         var todoTreeChildren = document.getElementById(listID);
  527.         while (todoTreeChildren.hasChildNodes()) {
  528.             todoTreeChildren.removeChild(todoTreeChildren.firstChild);
  529.           }        
  530. }
  531.  
  532. function reminderFox_enableAddTodoButton(event) {
  533.         var newbutton= document.getElementById("newTodoButton");
  534.         newbutton.removeAttribute( "disabled");
  535. }
  536.  
  537.  
  538. function rmFx_checkLoaded() {
  539.  
  540.     if (getAllSelectedReminders().length == 0) {
  541.         document.getElementById("treechildren-contextmenu-sendReminder").setAttribute("disabled", "true");
  542.     }    
  543.     if (getAllSelectedTodos().length == 0) {
  544.         document.getElementById("treechildren-contextmenu-sendTodos").setAttribute("disabled", "true");
  545.     }    
  546. }
  547.  
  548.  
  549. function loadReminders() {
  550.            showCalendar();
  551.  
  552.     //gW_Contact Handling           
  553.            rmFxMsg.whichMessenger();          
  554.         var addContext = document.getElementById("treechildren-contextmenu");
  555.         if (addContext != null)
  556.              addContext.addEventListener("popupshowing", rmFxPopupCheckContact, false);
  557.  
  558.         var addContext = document.getElementById("todo-treechildren-contextmenu");
  559.         if (addContext != null)
  560.              addContext.addEventListener("popupshowing", rmFxPopupCheckContact, false); 
  561.  
  562.     //gW_View Current    <<<------
  563.     rmFx_View.LoadCurrentPref();
  564.     rmFx_ViewSetTitel(rmFxViewLabel, rmFxViewItems);
  565.      
  566.     try {
  567.         dateVariableString = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LIST_DATE_LABEL);
  568.         if ( dateVariableString != REMINDER_FOX_LIST_DATE_LABEL_DEFAULT) {
  569.             useDefaultDate = false;
  570.         }
  571.     } catch(e) {
  572.          dateVariableString = REMINDER_FOX_LIST_DATE_LABEL_DEFAULT;
  573.     }    
  574.     
  575.     
  576.     reminderFox_highlightTodayPreference = REMINDER_FOX_HIGHLIGHT_TODAYS_REMINDERS_DEFAULT;            
  577.     try {
  578.         reminderFox_highlightTodayPreference = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_HIGHLIGHT_TODAYS_REMINDERS);
  579.     } catch(e) {
  580.     }            
  581.  
  582.     try {
  583.         REPEAT_PREVIOUS_OCCURRENCES = reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_REPEAT_PREVIOUS_OCCURRENCES);
  584.     } catch(e) {
  585.          REPEAT_PREVIOUS_OCCURRENCES = -1;
  586.     }    
  587.  
  588.     try {
  589.         REPEAT_UPCOMING_OCCURRENCES =  reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_REPEAT_UPCOMING_OCCURRENCES);
  590.     } catch(e) {
  591.          REPEAT_UPCOMING_OCCURRENCES = -1;
  592.     }        
  593.     
  594.     try {
  595.         HIDE_COMPLETED_ITEMS =  reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_HIDE_COMPLETED_ITEMS);
  596.     } catch(e) {
  597.          HIDE_COMPLETED_ITEMS = false;
  598.     }            
  599.     var hideCompletedContextMenu = document.getElementById("treechildren-contextmenu-hideCompleted");
  600.     var hideCompletedTodosContextMenu = document.getElementById("treechildren-contextmenu-hideCompleted2");
  601.     if ( HIDE_COMPLETED_ITEMS ) {
  602.         hideCompletedContextMenu.setAttribute("checked", "true");        
  603.         hideCompletedTodosContextMenu.setAttribute("checked", "true");        
  604.     }
  605.     else {
  606.         hideCompletedContextMenu.setAttribute("checked", "false");        
  607.         hideCompletedTodosContextMenu.setAttribute("checked", "false");        
  608.     }
  609.     
  610.     // set default filters
  611.     var defaultFilterReminderIndex = reminderFox_getPreferenceValue( REMINDER_FOX_DEFAULT_FILTER_REMINDER, 0 );
  612.     var filterList = document.getElementById("displayType");
  613.     filterList.selectedIndex = defaultFilterReminderIndex;    
  614.     
  615.     var defaultFilterTodoIndex = reminderFox_getPreferenceValue( REMINDER_FOX_DEFAULT_FILTER_TODO, 0 );
  616.     filterList = document.getElementById("displayTypeTodo");
  617.     filterList.selectedIndex = defaultFilterTodoIndex;    
  618.     
  619.     // create todo lists
  620.      var todoLists = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_TODO_LISTS);
  621.      if ( todoLists == null ) {
  622.          todoLists = "";
  623.      }
  624.      
  625.      // check to see if we need to update the todoLists....
  626.      var update = false;
  627.      var todosArr =    reminderFox_getReminderTodos();
  628.      var todoListsArray = todoLists.split(",");
  629.      for ( var n in todosArr ) {
  630.          if ( n !=REMINDER_FOX_DEFAULT_TODOS_CATEGORY ) {
  631.              var found = false;
  632.             for ( var i = 0; i < todoListsArray.length; i++ ) {
  633.                 if ( n == todoListsArray[i]) {
  634.                     found = true;
  635.                     break;
  636.                 }
  637.             }
  638.             if ( !found ) {
  639.                 if ( todoLists.length > 0 ) {
  640.                     todoLists = todoLists + "," + n;
  641.                 }
  642.                 else {
  643.                     todoLists = n;
  644.                 }
  645.                 update = true;
  646.             }
  647.          }
  648.     }
  649.     if ( update ) {
  650.         reminderFox_setUnicodePref( REMINDER_FOX_TODO_LISTS, todoLists);        
  651.     }
  652.     
  653.     
  654.      
  655.     if ( todoLists != null  && todoLists.length > 0 ) {
  656.         var todoListsArray = todoLists.split(",");
  657.         var tabList = document.getElementById("tabList");        
  658.         var panels = document.getElementById("tabPanelID");    
  659.         var todosTab = document.getElementById("todosPanel");
  660.         var remindersTab = document.getElementById("reminderPanel");
  661.         
  662.         for ( var i = 0; i < todoListsArray.length; i++ ) { 
  663.             var tabListItem = reminderFox_trim( todoListsArray[i] );    
  664.             var newTabList = document.createElement("tab");
  665.             newTabList.setAttribute( "id",   "reminderFoxList:" + tabListItem );
  666.             newTabList.setAttribute( "label", tabListItem );
  667.             tabList.appendChild(newTabList);
  668.             
  669.             var newtabpanel = todosTab.cloneNode( false );                            
  670.             newtabpanel.setAttribute( "id","reinderFoxListPanel:" + tabListItem  );
  671.             panels.appendChild(newtabpanel);
  672.         }
  673.     }
  674.     
  675.     // get sort columns
  676.     listSortMap = new Array();
  677.     var sortColumnsStr = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_SORT_COLUMNS_PREF);
  678.      if ( sortColumnsStr != null && sortColumnsStr != ""  ) {
  679.          var sortColumnsStrArray = sortColumnsStr.split(",");
  680.          for ( var i = 0; i < sortColumnsStrArray.length; i++ ) { 
  681.             var listName =  sortColumnsStrArray[i];
  682.             i++;
  683.             var sortCol = sortColumnsStrArray[i];
  684.             i++;
  685.             var sortDir = parseInt( sortColumnsStrArray[i] );
  686.             listSortMap[listName] = { sortColumn: sortCol, sortDirection:  sortDir };
  687.          }
  688.      }
  689.          
  690.     var syncedUp = reminderFox_ensureRemindersSynchronized();
  691.  
  692.     if ( isTodoTabSorted()) {
  693.         reminderFoxTabDirtied = true;  // we need to refill the todo tab the first time you select it to resort it
  694.     }
  695.  
  696.     fillList(true, true); 
  697.  
  698.     // select appropriate tab
  699.     if ( window.arguments != null ) {
  700.         var currentTab = window.arguments[0];
  701.         if ( currentTab == "todos" ) {
  702.             var todosTab = document.getElementById("todosTab");
  703.             var tabbox = document.getElementById("tabbox");
  704.             tabbox.selectedTab = todosTab;        
  705.         }
  706.     }
  707.     
  708.        //showCalendar();
  709.     
  710.     var todaysDate = new Date();
  711.     oeDatePicker.onpopupshowing(todaysDate);
  712.     selectCalendarSync = true;    
  713.  
  714.     rmFx_View.Clone();
  715.  
  716.     // dynamically insert Quick-Search box 
  717.     rmShowQSearch();  //false=no update "fillLists"  //gW_Search 
  718.  
  719.     // start synchronizing in background (if that network option is set)
  720.     setTimeout( reminderFox_ensureRemoteRemindersSynchronizedInEditWindow, 1 );
  721.     
  722.     if ( window.arguments != null  && window.arguments[1] != null ) { 
  723.         var editReminderID = window.arguments[1]. editID;
  724.         if ( editReminderID != null ) {
  725.             if (  window.arguments[1].isAReminder == "true" ) {
  726.                 selectReminderById(editReminderID    );
  727.                 window.setTimeout( editReminder, 1 );    
  728.             }
  729.             else {
  730.                 selectTodoById( window.arguments[1].todoList, editReminderID    );
  731.                 window.setTimeout( editTodo, 1 );    
  732.             }
  733.         }
  734.     }    
  735. }
  736.  
  737.  
  738. function reminderFox_ensureRemoteRemindersSynchronizedInEditWindow() {
  739.     // sync 'em up 
  740.     var networkSync = REMINDER_FOX_NETWORK_SYNCHRONIZE_DEFAULT;        
  741.     try {
  742.         networkSync = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_NETWORK_SYNCHRONIZE);
  743.     } catch(e) {
  744.     }    
  745.     if ( networkSync ) {
  746.         rmFxCore.statusSet (g_reminderFoxBundle.getString("rf.add.network.status.label"));
  747.         reminderFox_download_Startup_headless(REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS,reminderFox_synchronizeEditWindowCallback );
  748.     }    
  749. }
  750.  
  751. function reminderFox_synchronizeEditWindowCallback( statustxtString, actionID) {
  752.         // var statusTxt = document.getElementById("reminderFox-network-status");
  753.         
  754.         if ( actionID == 1 ) {  // completed successfully (remote and local are equal, or were uploaded)
  755.             rmFxCore.statusSet ("");
  756.                
  757.         }
  758.         else if ( actionID == 2 ) { // reminders were downloaded,  need to refresh reminders 
  759.             modifiedReminders();
  760.  
  761.             reminderFox_clearRemindersAndTodos();        
  762.             
  763.             selectCalendarSync = false;
  764.              // remove all of the calendar items and re-add them
  765.             removeAllListItems( true, true);      
  766.             calendarReminderArray = null;  // null out in case reminder columns are sorted
  767.             calendarTodoArray = null;
  768.             fillList(true, true);    
  769.             selectCalendarSync = true;   
  770.            
  771.            oeDatePicker.redrawYear();
  772.            oeDatePicker.redrawDays();            
  773.         //  statusTxt.setAttribute("value", "");   
  774.             rmFxCore.statusSet ("");
  775.            
  776.             // check to see if a reminder is being edited (such as if you opened the edit window from an alarm).
  777.             // If so, then we need to replace the old reminder instance (which is no longer in memory) with a newly
  778.             // retrieved one from the new model in memory
  779.            var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  780.            var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  781.            var topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxReminderOptionsDialog");
  782.            if (topWindow) {         
  783.                 var staleReminder =topWindow. arguments[0].reminder;
  784.                 if ( staleReminder != null ) {
  785.                     var refreshedReminder = reminderFox_getRemindersById( staleReminder.id, getCurrentReminderList()  );
  786.                     if  ( refreshedReminder != null ) {
  787.                         topWindow. arguments[0].reminder = refreshedReminder;
  788.                     }
  789.                 }
  790.            }             
  791.         }
  792.         else {
  793. //            statusTxt.setAttribute("value", statustxtString);
  794.             rmFxCore.statusSet (statustxtString);
  795.         }
  796.         
  797. }
  798.  
  799. function repopulateListForYear(oldYear, newYear) {
  800.     selectCalendarSync = false;
  801.      // remove all of the calendar items and re-add them
  802.     removeAllListItems( true, false);     
  803.     calendarReminderArray = null;  // null out in case reminder columns are sorted
  804.     calendarTodoArray = null;
  805.     fillList(true, false);    
  806.     selectCalendarSync = true;
  807. }
  808.  
  809. function fillList(  fillReminders,  fillTodoList, ignoreHighlight) {
  810.  
  811.     var i;
  812.     
  813.     if ( fillReminders ) {
  814.         if ( isTabSorted() ) {    
  815.             ignoreHighlight = true;
  816.             var tabList = document.getElementById("tabList");    
  817.             var tab =    tabList.selectedItem;
  818.             var tabName = tab.getAttribute( "label");
  819.              var direction = listSortMap[tabName].sortDirection;
  820.              if ( direction == REMINDER_FOX_SORT_DIRECTION_ASCENDING ) {
  821.                  var columnName  = listSortMap[tabName].sortColumn;
  822.                 if ( columnName == "dateColLabel"  ) {
  823.                     ignoreHighlight = false;
  824.                 }
  825.              }
  826.             
  827.             fillListSortReminders(true); 
  828.             
  829.             if ( !ignoreHighlight ) {
  830.                 // Note: need to launch this as a separate thread as in FF3.0 when dealing with remote 
  831.                 // calendars downloading, this call calls tree.select() which fails for some reason (must
  832.                 // be some thread/timing issue.  Calling this separate thread seems to fix it
  833.                 setTimeout( highlightClosestUpcomingReminder, 0, new Date());        
  834.                 //highlightClosestUpcomingReminder( new Date());        
  835.             }
  836.             
  837.         }
  838.         else { 
  839.             clearAllSortColumns();  // or could put this in the select tab logic...  may be better
  840.             createCalendarReminderArray();
  841.             var todaysDate = new Date();
  842.             var monthArray, dayReminderArray;
  843.             var monthIndex, dayIndex, reminderIndex;
  844.             for ( monthIndex = 0; monthIndex < 12; monthIndex++ ) {
  845.                 monthArray = calendarReminderArray[monthIndex];
  846.                 if ( monthArray != null ) {
  847.                     for ( dayIndex = 0; dayIndex < 31; dayIndex++ ) {
  848.                         dayReminderArray = monthArray[dayIndex];
  849.                         if ( dayReminderArray != null ) {
  850.                             for ( reminderIndex = 0; reminderIndex < dayReminderArray.length; reminderIndex++ ) {
  851.                                 createListItemSorted(dayReminderArray[reminderIndex], todaysDate);
  852.                             }
  853.                         }
  854.                     }
  855.                 }
  856.             }
  857.             // now that we've added the sorted reminders in the list, let's
  858.             // select (highlight) today's reminder or the next upcoming reminder
  859.             if ( !ignoreHighlight ) {
  860.                 // Note: need to launch this as a separate thread as in FF3.0 when dealing with remote 
  861.                 // calendars downloading, this call calls tree.select() which fails for some reason (must
  862.                 // be some thread/timing issue.  Calling this separate thread seems to fix it
  863.                 setTimeout( highlightClosestUpcomingReminder, 0, new Date());        
  864.                 //highlightClosestUpcomingReminder( new Date());        
  865.             }
  866.             
  867.             // bit of a hack here - for some reason at some times these filtered elements were indeed added to the 
  868.             // treechildren, but wouldn't show in the UI.  calling the treeselection.select() seemed to fix that, but 
  869.             // not sure why - possibly that the current view was scrolled off the screen
  870.             if ( isListFiltered() ) {
  871.                 var treeChildren = document.getElementById("treechildren");
  872.                 var treeSelection = document.getElementById("reminderTree").view.selection;    
  873.                 var treeitems = treeChildren.childNodes;
  874.                 if ( treeitems.length > 0 ) {
  875.                     //treeSelection.select(0);
  876.                     //highlightClosestUpcomingReminder( new Date());        
  877.                     setTimeout( treeSelect, 0);    
  878.                     setTimeout( highlightClosestUpcomingReminder, 0, new Date());    
  879.                 }
  880.             }
  881.         }
  882.     }
  883.     
  884.     if ( fillTodoList ) {
  885.         //calendarTodoArray = null;
  886.         createCalendarTodoArray()        
  887.         
  888.         if ( isTabSorted() ) {
  889.             fillListSortTodos();
  890.         }
  891.         else {
  892.             clearAllSortColumns();    //  or could put this in the select tab logic...  may be better
  893.             
  894.             var displayList = document.getElementById("displayTypeTodo");
  895.             // if one of the filters is set, only show those dates in the calendar array            
  896.             if ( displayList != null && displayList.selectedIndex > 0 ) {
  897.                 var todaysDate = new Date();
  898.                 var monthArray, dayReminderArray;
  899.                 var monthIndex, dayIndex, reminderIndex;
  900.                 for ( monthIndex = 0; monthIndex < 12; monthIndex++ ) {
  901.                     monthArray = calendarTodoArray[monthIndex];
  902.                     if ( monthArray != null ) {
  903.                         for ( dayIndex = 0; dayIndex < 31; dayIndex++ ) {
  904.                             dayReminderArray = monthArray[dayIndex];
  905.                             if ( dayReminderArray != null ) {
  906.                                 for ( reminderIndex = 0; reminderIndex < dayReminderArray.length; reminderIndex++ ) {
  907.                                     createTodoListItem(dayReminderArray[reminderIndex], false, todaysDate, false);
  908.                                 }
  909.                             }
  910.                         }
  911.                     }
  912.                 }                 
  913.             }
  914.             
  915.             else {
  916.                 
  917.                 // put that other check in the createTodoArray  
  918.                 var todaysDate = new Date();
  919.                 var reminderTodos = getCurrentTodoList();
  920.                  for( i = 0; i < reminderTodos.length; i++) {             
  921.                     createTodoListItem(reminderTodos[i], false, todaysDate, false);
  922.                 }
  923.                 highlightTodo();
  924.             }
  925.         }
  926.     }
  927.        selectNewReminderText();
  928. }
  929.  
  930. function treeSelect() {
  931.     var treeSelection = document.getElementById("reminderTree").view.selection;    
  932.     var treeChildren = document.getElementById("treechildren");
  933.     var treeitems = treeChildren.childNodes;
  934.     if ( treeitems.length > 0 ) {
  935.         treeSelection.select(0);
  936.     }
  937. }
  938.  
  939. function doFindNext() {
  940.     if ( lastSearchString == null ) {
  941.         doFind();
  942.     }
  943.     else {
  944.         if ( !isReminderTabSelected() ) {
  945.              findTodo();
  946.         }
  947.         else {
  948.              findReminder();
  949.         }
  950.     }
  951. }
  952.  
  953. function doShowAll() {
  954.     SHOW_ALL_REMINDERS = true;
  955.     HIDE_ALL_REMINDERS = false;
  956.     
  957.    // redraw the year and the days
  958.    repopulateListForYear( null , oeDatePicker.gSelectedDate.getFullYear() );
  959.    
  960.    oeDatePicker.redrawYear();
  961.    oeDatePicker.redrawDays();
  962. }
  963.  
  964. function doHideAll() {
  965.     SHOW_ALL_REMINDERS = false;
  966.     HIDE_ALL_REMINDERS = true;
  967.     
  968.    // redraw the year and the days
  969.    repopulateListForYear( null , oeDatePicker.gSelectedDate.getFullYear() );
  970.    
  971.    oeDatePicker.redrawYear();
  972.    oeDatePicker.redrawDays();
  973. }
  974.  
  975. function toggleHideCompletedItems() {
  976.     HIDE_COMPLETED_ITEMS = !HIDE_COMPLETED_ITEMS;
  977.     
  978.     var hideCompletedContextMenu = document.getElementById("treechildren-contextmenu-hideCompleted");
  979.     var hideCompletedTodosContextMenu = document.getElementById("treechildren-contextmenu-hideCompleted2");
  980.     if ( HIDE_COMPLETED_ITEMS ) {
  981.         hideCompletedContextMenu.setAttribute("checked", "true");        
  982.         hideCompletedTodosContextMenu.setAttribute("checked", "true");        
  983.     }
  984.     else {
  985.         hideCompletedContextMenu.setAttribute("checked", "false");        
  986.         hideCompletedTodosContextMenu.setAttribute("checked", "false");        
  987.     }    
  988.     
  989.    // redraw the year and the days
  990.    //repopulateListForYear( null , oeDatePicker.gSelectedDate.getFullYear() );
  991.     selectCalendarSync = false;
  992.      // remove all of the calendar items and re-add them
  993.     removeAllListItems( true, true);      
  994.     fillList(true, true);    
  995.     selectCalendarSync = true;   
  996.    
  997.    oeDatePicker.redrawYear();
  998.    oeDatePicker.redrawDays();
  999. }
  1000.  
  1001.  
  1002. function doFind() {
  1003.     var nsIPromptService = Components.interfaces.nsIPromptService;
  1004.     var nsPrompt_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
  1005.     var gPromptService = Components.classes[nsPrompt_CONTRACTID].getService(nsIPromptService);
  1006.     var result = { value: lastSearchString };
  1007.     var dummy = { value: 0 };
  1008.     var title;
  1009.     if ( !isReminderTabSelected() ) {
  1010.          title =  g_reminderFoxBundle.getString("rf.add.find.todo.title");
  1011.     }
  1012.     else {
  1013.          title =  g_reminderFoxBundle.getString("rf.add.find.title");
  1014.     }
  1015.     
  1016.     if (gPromptService.prompt(window,
  1017.                             title,
  1018.                             g_reminderFoxBundle.getString("rf.add.find.description"),
  1019.                             result,
  1020.                             null,
  1021.                             dummy)) {
  1022.                             
  1023.             lastSearchString = result.value;
  1024.           
  1025.             // only bring up find dialog if reminders tab is selected
  1026.             if ( isReminderTabSelected() ) {
  1027.                 findReminder();          
  1028.             }
  1029.             else {
  1030.                 findTodo();
  1031.             }          
  1032.             
  1033.     }    
  1034. }
  1035.  
  1036. function findReminder( ) {
  1037.     var i;
  1038.     var item;
  1039.     var row;
  1040.     var descCell;
  1041.     var descCellLabel;
  1042.     
  1043.     var selectedTreeItemIndex = document.getElementById("reminderTree").currentIndex;
  1044.     // if nothing selected, default to start of list
  1045.     if ( selectedTreeItemIndex == -1 ) {
  1046.         selectedTreeItemIndex = 0;
  1047.     }
  1048.         
  1049.     var treeChildren = document.getElementById("treechildren");
  1050.     var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  1051.  
  1052.     var dateLabel = selectedTreeItem.childNodes[0].childNodes[0].getAttribute("label");
  1053.     var descLabel = selectedTreeItem.childNodes[0].childNodes[1].getAttribute("label");
  1054.       var caseInsensitiveLastSearchString = lastSearchString.toUpperCase();
  1055.  
  1056.     var treeitems = treeChildren.childNodes;
  1057.     var startIndex = selectedTreeItemIndex;
  1058.     if ( startIndex + 1 < treeitems.length ) {
  1059.         startIndex = startIndex + 1;
  1060.     }
  1061.     else { 
  1062.         startIndex = 0;
  1063.     }
  1064.  
  1065.     var foundIndex = -1;
  1066.     for ( i=startIndex; i < treeitems.length; i++) {
  1067.         item = treeitems[i];
  1068.         row = item.childNodes[0];
  1069.         descCell = row.childNodes[1];
  1070.         descCellLabel = descCell.getAttribute("label");
  1071.         descCellLabel = descCellLabel.toUpperCase();
  1072.  
  1073.         if ( descCellLabel.indexOf( caseInsensitiveLastSearchString ) != -1  ) {
  1074.             foundIndex = i;
  1075.  
  1076.             break;
  1077.         }
  1078.     }
  1079.     
  1080.     if ( foundIndex == -1 ) {
  1081.         for ( i=0; i < startIndex; i++) {
  1082.             item = treeitems[i];
  1083.              row = item.childNodes[0];
  1084.             descCell = row.childNodes[1];
  1085.             descCellLabel = descCell.getAttribute("label");
  1086.             descCellLabel = descCellLabel.toUpperCase();
  1087.  
  1088.             if ( descCellLabel.indexOf( caseInsensitiveLastSearchString ) != -1  ) {
  1089.                 foundIndex = i;
  1090.                 break;
  1091.             }
  1092.         }
  1093.     }
  1094.     
  1095.     // if we found a search match, then highlight the new reminder in the list
  1096.     if ( foundIndex != -1 ) {        
  1097.         var treeSelection = document.getElementById("reminderTree").view.selection        
  1098.         treeSelection.select(foundIndex);
  1099.         
  1100.         // make sure that newly selected row is shown in scroll pane
  1101.         var value = document.getElementById("treeparent").value;
  1102.           var tree = document.getElementById("reminderTree");            
  1103.         var boxobject = tree.boxObject;
  1104.         boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  1105.         
  1106.         // make sure it shows up at the top if possible
  1107.         var first = boxobject.getFirstVisibleRow();
  1108.         var last = boxobject.getLastVisibleRow();
  1109.         if ( foundIndex < first || foundIndex > last ) {                
  1110.             boxobject.scrollToRow(treeitems.length - 9);
  1111.         }
  1112.         
  1113.         var previousReminderOffset = 3;
  1114.         if ( foundIndex < previousReminderOffset ) { 
  1115.             boxobject.ensureRowIsVisible(i);
  1116.         }
  1117.         else {
  1118.             boxobject.ensureRowIsVisible(foundIndex  - previousReminderOffset);
  1119.         }
  1120.     }
  1121. }
  1122.  
  1123.  
  1124. function findTodo( ) {
  1125.     var i;
  1126.     var item;
  1127.     var row;
  1128.     var descCell;
  1129.     var descCellLabel;
  1130.     
  1131.     var selectedTreeItemIndex = document.getElementById("todoTree").currentIndex;
  1132.     // if nothing selected, default to start of list
  1133.     if ( selectedTreeItemIndex == -1 ) {
  1134.         selectedTreeItemIndex = 0;
  1135.     }
  1136.         
  1137.     var treeChildren = document.getElementById("todoTreechildren");
  1138.     var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  1139.  
  1140.     var descLabel = selectedTreeItem.childNodes[0].childNodes[1].getAttribute("label"); // 1 is description for Todos
  1141.     var caseInsensitiveLastSearchString = lastSearchString.toUpperCase();
  1142.  
  1143.     var treeitems = treeChildren.childNodes;
  1144.     var startIndex = selectedTreeItemIndex;
  1145.     if ( startIndex + 1 < treeitems.length ) {
  1146.         startIndex = startIndex + 1;
  1147.     }
  1148.     else { 
  1149.         startIndex = 0;
  1150.     }
  1151.  
  1152.     var foundIndex = -1;
  1153.     for ( i=startIndex; i < treeitems.length; i++) {
  1154.         item = treeitems[i];
  1155.         row = item.childNodes[0];
  1156.         descCell = row.childNodes[1]; // 1 is description for todo's
  1157.         descCellLabel = descCell.getAttribute("label");
  1158.         descCellLabel = descCellLabel.toUpperCase();
  1159.         if ( descCellLabel.indexOf( caseInsensitiveLastSearchString ) != -1  ) {
  1160.             foundIndex = i;
  1161.  
  1162.             break;
  1163.         }
  1164.     }
  1165.     
  1166.     if ( foundIndex == -1 ) {
  1167.         for ( i=0; i < startIndex; i++) {
  1168.             item = treeitems[i];
  1169.              row = item.childNodes[0];
  1170.             descCell = row.childNodes[1]; // 1 is description for ToDo's
  1171.             descCellLabel = descCell.getAttribute("label");
  1172.             descCellLabel = descCellLabel.toUpperCase();
  1173.  
  1174.             if ( descCellLabel.indexOf( caseInsensitiveLastSearchString ) != -1  ) {
  1175.                 foundIndex = i;
  1176.                 break;
  1177.             }
  1178.         }
  1179.     }
  1180.     
  1181.     // if we found a search match, then highlight the new reminder in the list
  1182.     if ( foundIndex != -1 ) {        
  1183.         var treeSelection = document.getElementById("todoTree").view.selection        
  1184.         treeSelection.select(foundIndex);
  1185.         
  1186.         // make sure that newly selected row is shown in scroll pane
  1187.         var value = document.getElementById("treeparent").value;
  1188.           var tree = document.getElementById("todoTree");            
  1189.         var boxobject = tree.boxObject;
  1190.         boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  1191.         
  1192.         // make sure it shows up at the top if possible
  1193.         var first = boxobject.getFirstVisibleRow();
  1194.         var last = boxobject.getLastVisibleRow();
  1195.         if ( foundIndex < first || foundIndex > last ) {                
  1196.             boxobject.scrollToRow(treeitems.length - 9);
  1197.         }
  1198.         
  1199.         var previousReminderOffset = 3;
  1200.         if ( foundIndex < previousReminderOffset ) { 
  1201.             boxobject.ensureRowIsVisible(i);
  1202.         }
  1203.         else {
  1204.             boxobject.ensureRowIsVisible(foundIndex  - previousReminderOffset);
  1205.         }
  1206.     }
  1207. }
  1208.  
  1209. function selectNewReminderText() {
  1210.    var desc = document.getElementById("addReminderButton");  
  1211.     desc.focus();
  1212. }
  1213.  
  1214.  
  1215. function toggleCalendar() {        
  1216.     var calendar = document.getElementById("oe-date-picker-overlay-box");        
  1217.     var calendarToggleButton;
  1218.     if ( isReminderTabSelected() ) {
  1219.         calendarToggleButton= document.getElementById("calendarToggle");
  1220.         if ( calendar.parentNode != document.getElementById("treeparent") ) {
  1221.             var clonedDatePicker = calendar.cloneNode( true );
  1222.             calendar.parentNode.removeChild( calendar );        
  1223.             document.getElementById("treeparent").appendChild( clonedDatePicker );
  1224.         }        
  1225.     }
  1226.     else {
  1227.         calendarToggleButton = document.getElementById("todoCalendarToggle");
  1228.         if ( calendar.parentNode != document.getElementById("todoTreeparent") ) {
  1229.             var clonedDatePicker = calendar.cloneNode( true );
  1230.             calendar.parentNode.removeChild( calendar );        
  1231.             document.getElementById("todoTreeparent").appendChild( clonedDatePicker );
  1232.         }
  1233.     }
  1234.     var newCalendarNode  = document.getElementById("oe-date-picker-overlay-box");        
  1235.     if ( calendarToggleButton.getAttribute( "checked" )  ) {
  1236.         newCalendarNode.setAttribute("hidden", "true");                    
  1237.         calendarToggleButton.setAttribute("tooltiptext", g_reminderFoxBundle.getString("rf.add.time.button.calendar.tooltip.show"));    
  1238.         calendarToggleButton.removeAttribute( "checked" )     
  1239.     }
  1240.     else {
  1241.         newCalendarNode.removeAttribute("hidden");
  1242.         calendarToggleButton.setAttribute("tooltiptext", g_reminderFoxBundle.getString("rf.add.time.button.calendar.tooltip.hide"));    
  1243.         calendarToggleButton.setAttribute( "checked", true );
  1244.     }
  1245. }
  1246.  
  1247. function showCalendar() {            
  1248.   // if not the default medium size, then we need to resize the calendar
  1249.   // In that case, we need to initially hide the calendar widget and then show it in a setTimeout thread
  1250.   // because on FF2.x, the sizing gets screwed up
  1251.   var calendarSize = 1;
  1252.   try {
  1253.         calendarSize = reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_CALENDAR_SIZE);
  1254.     } catch(e) {        
  1255.     }    
  1256.     if ( calendarSize != 1 ) { 
  1257.         oeDatePicker.resizeCalendar();
  1258.         var newCalendarNode  = document.getElementById("oe-date-picker-overlay-box");    
  1259.         newCalendarNode.setAttribute("hidden", "true");    
  1260.         setTimeout( reminderFox_showCal, 0);
  1261.     }
  1262.     else {
  1263.         reminderFox_showCal();
  1264.     }
  1265. }
  1266.  
  1267.  
  1268. function reminderFox_showCal() {
  1269.     var calendar = document.getElementById("oe-date-picker-overlay-box");        
  1270.     var calendarToggleButton;
  1271.     if ( isReminderTabSelected() ) {  
  1272.         calendarToggleButton= document.getElementById("calendarToggle");        
  1273.         if ( calendar.parentNode != document.getElementById("treeparent") ) {            
  1274.             var clonedDatePicker = calendar.cloneNode( true );
  1275.             calendar.parentNode.removeChild( calendar );        
  1276.             document.getElementById("treeparent").appendChild( clonedDatePicker );
  1277.         }
  1278.         
  1279.     }
  1280.     else {
  1281.         calendarToggleButton = document.getElementById("todoCalendarToggle");
  1282.         if ( calendar.parentNode != document.getElementById("todoTreeparent") ) {
  1283.             var clonedDatePicker = calendar.cloneNode( true );
  1284.             calendar.parentNode.removeChild( calendar );        
  1285.             document.getElementById("todoTreeparent").appendChild( clonedDatePicker );
  1286.         }
  1287.     }
  1288.     
  1289.     var newCalendarNode  = document.getElementById("oe-date-picker-overlay-box");        
  1290.     if ( calendarToggleButton.getAttribute( "checked" )  ) {
  1291.         newCalendarNode.removeAttribute("hidden");
  1292.         calendarToggleButton.setAttribute("tooltiptext", g_reminderFoxBundle.getString("rf.add.time.button.calendar.tooltip.hide"));    
  1293.     }
  1294.     else {
  1295.         newCalendarNode.setAttribute("hidden", "true");    
  1296.         calendarToggleButton.setAttribute("tooltiptext", g_reminderFoxBundle.getString("rf.add.time.button.calendar.tooltip.show"));
  1297.     }
  1298. }
  1299.  
  1300. function reminderSelected(event) {
  1301.     if ( selectCalendarSync ) {
  1302.         var selectedTreeItemIndex = document.getElementById("reminderTree").currentIndex; 
  1303.         if ( selectedTreeItemIndex >= 0 ) {
  1304.             var treeChildren = document.getElementById("treechildren");
  1305.             if ( treeChildren != null ) {
  1306.                 if ( selectedTreeItemIndex >= treeChildren.childNodes.length ) {
  1307.                     selectedTreeItemIndex = treeChildren.childNodes.length - 1;
  1308.                 } 
  1309.                 var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  1310.                 
  1311.                 var reminderDateTime = selectedTreeItem.childNodes[0].getAttribute(REMINDER_DATE_REF);    
  1312.                 var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  1313.                 oeDatePicker.onpopupshowing(reminderInstanceDate);
  1314.             }
  1315.         }
  1316.     }
  1317.     rmFxCore.statusSet ("");
  1318. }
  1319.  
  1320.  
  1321. function todoSelected(event) {
  1322.     if ( selectCalendarSync ) {
  1323.         var selectedTreeItemIndex = document.getElementById("todoTree").currentIndex; 
  1324.         if ( selectedTreeItemIndex >= 0 ) {
  1325.             var treeChildren = document.getElementById("todoTreechildren");
  1326.             if ( treeChildren != null ) {
  1327.                 if ( selectedTreeItemIndex >= treeChildren.childNodes.length ) {
  1328.                     selectedTreeItemIndex = treeChildren.childNodes.length - 1;
  1329.                 } 
  1330.                 if ( selectedTreeItemIndex < 0 ) {
  1331.                     return;
  1332.                 }
  1333.                 var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  1334.                 var reminderDateTime = selectedTreeItem.childNodes[0].getAttribute(REMINDER_DATE_REF);    
  1335.                 if ( reminderDateTime != null  && reminderDateTime.length > 0) {
  1336.                     var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  1337.                     oeDatePicker.onpopupshowing(reminderInstanceDate);
  1338.                 }
  1339.             }
  1340.         }
  1341.     }
  1342.     rmFxCore.statusSet (""); 
  1343. }
  1344.  
  1345.  
  1346. function reminderFox_getReminderViewAsHTMLFile() {
  1347.     var file;
  1348.     var savefilePath;
  1349.     // check if user has specified a specific file path in their preferences
  1350.     try {
  1351.         //gW_OSswitching
  1352.         savefilePath = rmFx_getStoreFile4OS();
  1353.         //  support for OSswitch
  1354.         // savefilePath = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_STORE_FILE);
  1355.     }
  1356.     catch ( e) {
  1357.     }
  1358.     // if not, then use default location in profile
  1359.     if ( savefilePath == null || savefilePath == "" ) {
  1360.          file = Components.classes["@mozilla.org/file/directory_service;1"]
  1361.                  .getService(Components.interfaces.nsIProperties)
  1362.               .get("ProfD", Components.interfaces.nsIFile);
  1363.  
  1364.           file.append( "reminderfox" );
  1365.           file.append( "reminderfox.ics" + ".html" );            
  1366.     }
  1367.     else {
  1368.         savefilePath = savefilePath + ".html";
  1369.         file = Components.classes["@mozilla.org/file/local;1"]
  1370.                     .createInstance(Components.interfaces.nsILocalFile);
  1371.         file.initWithPath( savefilePath );
  1372.     }
  1373.     return file;
  1374. }
  1375.  
  1376.  
  1377. function doShowHTML() {
  1378.     
  1379.     var tabList = document.getElementById("tabList");    
  1380.     var tab =    tabList.selectedItem;
  1381.     var listName = tab.getAttribute( "label");
  1382.     
  1383.     var outputStr = "";
  1384.     
  1385.     outputStr += "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 // Transitional//EN\">\n";
  1386.     outputStr += "<HTML>\n";
  1387.     
  1388.     outputStr += "<HEAD>\n";
  1389.     
  1390.     outputStr += "<TITLE>" + g_reminderFoxBundle.getString("rf.title") + "</TITLE>\n";
  1391.     //outputStr += "<link rel=\"shortcut icon\" href=\"" + REMINDER_FOX_REMIND_UNTIL_COMPLETED_IMAGE + "\" type=\"image/png\" >\n";
  1392.     outputStr += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
  1393.     
  1394.     var stylesheet = reminderFox_getPreferenceValue( REMINDER_FOX_HTML_STYLESHEET_PREF );
  1395.     if ( stylesheet != null && stylesheet.length > 0 ) {  // do for showReminders too
  1396.         outputStr += "<link rel=\"stylesheet\" href=\"" + stylesheet + "\" type=\"text/css\">\n";
  1397.     }
  1398.     outputStr += "</HEAD>\n";
  1399.     outputStr += "<div id=\"main\">\n";    
  1400.     
  1401.     if ( stylesheet != null && stylesheet.length > 0 ) { // don't need title if not using styleshet 
  1402.         outputStr += "<h4>" + listName + "</h4>\n";
  1403.     }
  1404.         
  1405.     outputStr += "<BODY>\n";
  1406.     
  1407.     outputStr += "<TABLE border=\"1\">\n";
  1408.     outputStr += "<TBODY>\n";    
  1409.     outputStr += "  <TR>\n";
  1410.     
  1411.     outputStr += "    <TD>\n";
  1412.     outputStr += "      <b>" + g_reminderFoxBundle.getString("rf.html.heading.date") + "</b>\n";
  1413.     outputStr += "    </TD>\n";
  1414.     
  1415.     outputStr += "    <TD>\n";
  1416.     outputStr += "      <b>" + g_reminderFoxBundle.getString("rf.html.heading.reminder") + "</b>\n";
  1417.     outputStr += "    </TD>\n";
  1418.     
  1419.     outputStr +=  "    <TD>\n";
  1420.     outputStr += "      <b>" + g_reminderFoxBundle.getString("rf.html.heading.time") + "</b>\n";
  1421.     outputStr += "    </TD>\n";    
  1422.     
  1423.     outputStr += "  </TR>\n";        
  1424.  
  1425.     var i;
  1426.     var item;
  1427.     var row;
  1428.     var dateCell;
  1429.     var dateCellLabel    
  1430.     var descCell;
  1431.     var descCellLabel;
  1432.     var timeCell;
  1433.     var timeCellLabel;    
  1434.         
  1435.     var treeChildren = document.getElementById("treechildren");
  1436.     var treeitems = treeChildren.childNodes;
  1437.     
  1438.     
  1439.     var indices = null;
  1440.     var multipleRemindersSelected = getAllSelectedReminderIndices();
  1441.     if ( multipleRemindersSelected.length > 1 ) {
  1442.         indices = multipleRemindersSelected;
  1443.     }
  1444.     else {
  1445.         indices = new Array(treeitems.length);
  1446.         for (  i = 0; i < treeitems.length; i++ ) {
  1447.             indices[i] = i;
  1448.         }
  1449.     }
  1450.  
  1451.     for ( i=0; i < indices.length; i++) { 
  1452.         item = treeitems[indices[i]];
  1453.         row = item.childNodes[0];
  1454.         dateCell = row.childNodes[0];
  1455.         dateCellLabel = dateCell.getAttribute("label");        
  1456.         dateCellLabel = dateCellLabel.replace(new RegExp(/ /g)," ");  
  1457.         descCell = row.childNodes[1];
  1458.         descCellLabel = descCell.getAttribute("label");
  1459.         timeCell = row.childNodes[2];
  1460.         timeCellLabel = timeCell.getAttribute("label");        
  1461.         timeCellLabel = timeCellLabel.replace(new RegExp(/ /g)," ");  
  1462.         
  1463.         var important = descCell.getAttribute("properties" ) == "important" || 
  1464.             descCell.getAttribute("properties" ) == "imporantCompleteTextToday" ||         
  1465.             descCell.getAttribute( "properties" ) == "imporantCompleteText";
  1466.         var completed = descCell.getAttribute("properties" ) == "completeText" ||
  1467.             descCell.getAttribute("properties" ) == "imporantCompleteTextToday" ||
  1468.             descCell.getAttribute( "properties" ) == "imporantCompleteText";            
  1469.                     
  1470.         outputStr +=  "  <TR>\n";
  1471.  
  1472.         outputStr +=  "    <TD>\n";
  1473.         if ( important ) {
  1474.             outputStr +=  "    <FONT color=\"FF0000\">\n";
  1475.         }    
  1476.         if ( completed ) {
  1477.             outputStr +=  "    <del>\n";
  1478.         }
  1479.         outputStr +=  "      " ;
  1480.         outputStr += dateCellLabel + "\n";
  1481.         if ( important ) {
  1482.             outputStr +=  "    </FONT>\n";
  1483.         }    
  1484.         if ( completed ) {
  1485.             outputStr +=  "    </del>\n";
  1486.         }
  1487.         outputStr +=  "    </TD>\n";
  1488.         
  1489.         outputStr +=  "    <TD>\n";
  1490.         if ( important ) {
  1491.             outputStr +=  "    <FONT color=\"FF0000\">\n";
  1492.         }    
  1493.         if ( completed ) {
  1494.             outputStr +=  "    <del>\n";
  1495.         }        
  1496.         outputStr +=  "      " ;
  1497.         outputStr +=  descCellLabel + '\n';
  1498.         if ( important ) {
  1499.             outputStr +=  "    </FONT>\n";
  1500.         }            
  1501.         if ( completed ) {
  1502.             outputStr +=  "    </del>\n";
  1503.         }
  1504.         outputStr +=  "    </TD>\n";        
  1505.         
  1506.         outputStr +=  "    <TD>\n";
  1507.         if ( important ) {
  1508.             outputStr +=  "    <FONT color=\"FF0000\">\n";
  1509.         }    
  1510.         if ( completed ) {
  1511.             outputStr +=  "    <del>\n";
  1512.         }        
  1513.         outputStr +=  "      " ;
  1514.         outputStr +=  timeCellLabel + '\n';
  1515.         if (important ) {
  1516.             outputStr +=  "    </FONT>\n";
  1517.         }        
  1518.         if ( completed ) {
  1519.             outputStr +=  "    </del>\n";
  1520.         }
  1521.         outputStr +=  "    </TD>\n";                
  1522.  
  1523.         
  1524.         outputStr +=  "  </TR>\n";    
  1525.  
  1526.         // output notes if available
  1527.         // want to replace in notes: ("\n", "<BR/>") to get line breaks
  1528.         var reminder =  reminderFox_getRemindersById( row.getAttribute(REMINDER_ID_REF), getCurrentReminderList() );
  1529.          if ( reminder != null  && reminder.notes != null ) {         
  1530.             outputStr +=  "  <TR>\n";
  1531.             
  1532.             outputStr +=  "    <TD>\n";
  1533.             outputStr +=  "    </TD>\n";
  1534.             
  1535.             outputStr +=  "    <TD>\n";
  1536.             var notes = reminder.notes;
  1537.             notes = notes.replace(new RegExp(/\n/g),"<BR/>");      
  1538.             outputStr +=  "      " + notes;
  1539.             
  1540.             outputStr +=  "    </TD>\n";        
  1541.             
  1542.             outputStr +=  "    <TD>\n";
  1543.             outputStr +=  "    </TD>\n";
  1544.             
  1545.             outputStr +=  "    <TD>\n";
  1546.             outputStr +=  "    </TD>\n";            
  1547.             
  1548.             outputStr +=  "  </TR>\n";    
  1549.          }        
  1550.         
  1551.     }    
  1552.     
  1553.     outputStr +=  " </TBODY>\n";
  1554.     outputStr +=  "</TABLE>\n";
  1555.     outputStr +=  "</BODY>\n";
  1556.     outputStr += "</div>\n"
  1557.     outputStr +=  "</HTML>\n";
  1558.     
  1559.     var file = reminderFox_getReminderViewAsHTMLFile();
  1560.     
  1561.     // now write file out to filesystem
  1562.     try {
  1563.         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  1564.     } catch (e) {
  1565.         alert("Permission to save file was denied.");
  1566.     }
  1567.  
  1568.     if ( file.exists() == false ) {
  1569.         file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 );
  1570.     }
  1571.  
  1572.     reminderFox_writeStringToFile(outputStr, file, true);
  1573.  
  1574.     var tempURL = "file:///" + file.path; 
  1575.     reminderFox_openURL(tempURL );
  1576.     //file.remove(false);  // can't remove here as it can be removed before the browser opens (in Thunderbird case)
  1577. }
  1578.  
  1579. function doShowToDosHTML() {
  1580.     var outputStr = "";
  1581.         
  1582.     // get list name for title
  1583.     var tabList = document.getElementById("tabList");    
  1584.     var tab =    tabList.selectedItem;
  1585.     var listName = tab.getAttribute( "label");
  1586.  
  1587.     outputStr += "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 // Transitional//EN\">\n";
  1588.  
  1589.     outputStr += "<HTML>\n";
  1590.     outputStr += "<HEAD>\n";
  1591.     outputStr += "<TITLE>" +g_reminderFoxBundle.getString("rf.title") + " - " + listName + "</TITLE>\n";
  1592.     outputStr += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
  1593.     
  1594.     var stylesheet = reminderFox_getPreferenceValue( REMINDER_FOX_HTML_STYLESHEET_PREF );
  1595.     if ( stylesheet != null && stylesheet.length > 0 ) {  
  1596.         outputStr += "<link rel=\"stylesheet\" href=\"" + stylesheet + "\" type=\"text/css\">\n";
  1597.     }
  1598.     outputStr += "</HEAD>\n";
  1599.     
  1600.     outputStr += "<div id=\"main\">\n";    
  1601.     
  1602.     if ( stylesheet != null && stylesheet.length > 0 ) { // don't need title if not using styleshet 
  1603.         outputStr += "<h4>" + listName + "</h4>\n";
  1604.     }
  1605.         
  1606.     outputStr += "<BODY>\n";
  1607.     outputStr += "<TABLE border=\"1\">\n";
  1608.     outputStr += " <TBODY>\n";    
  1609.     
  1610.     outputStr +=  "  <TR>\n";
  1611.     
  1612.     outputStr +=  "    <TD>\n";        
  1613.     outputStr +=  "      <b>" + g_reminderFoxBundle.getString("rf.html.heading.todo.number") + "</b>\n";
  1614.     outputStr +=  "    </TD>\n";
  1615.     
  1616.     outputStr +=  "    <TD>\n";    
  1617.     outputStr +=  "      <b>" + listName + "</b>\n";
  1618.     outputStr +=  "    </TD>\n";
  1619.     
  1620.     outputStr +=  "    <TD>\n";
  1621.     outputStr +=  "      <b>" + g_reminderFoxBundle.getString("rf.html.heading.date") + "</b>\n";
  1622.     outputStr +=  "    </TD>\n";    
  1623.     
  1624.     outputStr +=  "    <TD>\n";
  1625.     outputStr +=  "      <b>" + g_reminderFoxBundle.getString("rf.html.heading.time") + "</b>\n";
  1626.     outputStr +=  "    </TD>\n";        
  1627.     
  1628.     outputStr +=  "  </TR>\n";        
  1629.  
  1630.     var i;
  1631.     var item;
  1632.     var row;
  1633.     var dateCell;
  1634.     var dateCellLabel    
  1635.     var descCell;
  1636.     var descCellLabel;
  1637.     var timeCell;
  1638.     var timeCellLabel;    
  1639.         
  1640.     var treeChildren = document.getElementById("todoTreechildren");
  1641.     var treeitems = treeChildren.childNodes;
  1642.     
  1643.     
  1644.     
  1645.     var indices = null;
  1646.     var multipleTodosSelected = getAllSelectedTodoIndices();
  1647.     if ( multipleTodosSelected.length > 1 ) {
  1648.         indices = multipleTodosSelected;
  1649.     }
  1650.     else {
  1651.         indices = new Array(treeitems.length);
  1652.         for (  i = 0; i < treeitems.length; i++ ) {
  1653.             indices[i] = i;
  1654.         }
  1655.     }
  1656.  
  1657.     for ( i=0; i < indices.length; i++) {
  1658.         item = treeitems[indices[i]];    
  1659.         row = item.childNodes[0];        
  1660.         var todo = reminderFox_getTodosById( row.getAttribute(REMINDER_ID_REF),  getCurrentTodoList() );        
  1661.         
  1662.         dateCell = row.childNodes[0];
  1663.         dateCellLabel = dateCell.getAttribute("label");
  1664.         dateCellLabel = dateCellLabel.replace(new RegExp(/ /g)," ");  
  1665.         descCell = row.childNodes[1];
  1666.         descCellLabel = descCell.getAttribute("label");
  1667.         timeCell = row.childNodes[2];
  1668.         timeCellLabel = timeCell.getAttribute("label");        
  1669.         timeCellLabel = timeCellLabel.replace(new RegExp(/ /g)," ");  
  1670.         
  1671.         var important = descCell.getAttribute("properties" ) == "important" ||
  1672.             descCell.getAttribute( "properties" ) == "imporantCompleteText";
  1673.         var completed = descCell.getAttribute("properties" ) == "completeText" ||
  1674.             descCell.getAttribute( "properties" ) == "imporantCompleteText";                        
  1675.         
  1676.         outputStr +=  "  <TR>\n";
  1677.                 
  1678.         outputStr +=  "    <TD>\n";
  1679.         if ( important ) {
  1680.             outputStr +=  "    <FONT color=\"FF0000\">\n";
  1681.         }            
  1682.         if ( completed ) {
  1683.             outputStr +=  "    <del>\n";
  1684.         }        
  1685.         outputStr +=  "      ";        
  1686.         outputStr += (i+1) + "\n";  // +1 so we start with a 1-based index
  1687.         if ( important ) {
  1688.             outputStr +=  "    </FONT>\n";
  1689.         }        
  1690.         if ( completed ) {
  1691.             outputStr +=  "    </del>\n";
  1692.         }
  1693.         outputStr +=  "    </TD>\n";
  1694.         
  1695.         outputStr +=  "    <TD>\n";
  1696.         if ( important)  {
  1697.             outputStr +=  "    <FONT color=\"FF0000\">\n";
  1698.         }            
  1699.         if ( completed ) {
  1700.             outputStr +=  "    <del>\n";
  1701.         }        
  1702.         outputStr +=  "      " ;
  1703.         outputStr +=  descCellLabel + '\n';
  1704.         if ( important ) {
  1705.             outputStr +=  "    </FONT>\n";
  1706.         }            
  1707.         if ( completed ) {
  1708.             outputStr +=  "    </del>\n";
  1709.         }        
  1710.         outputStr +=  "    </TD>\n";        
  1711.         
  1712.         outputStr +=  "    <TD>\n";
  1713.         if ( important ) {
  1714.             outputStr +=  "    <FONT color=\"FF0000\">\n";
  1715.         }    
  1716.         if ( completed ) {
  1717.             outputStr +=  "    <del>\n";
  1718.         }        
  1719.         outputStr +=  "      " ;
  1720.         if ( dateCellLabel == "" ) {
  1721.             dateCellLabel = " ";
  1722.         }
  1723.         outputStr += dateCellLabel + "\n";
  1724.         if ( important ) {
  1725.             outputStr +=  "    </FONT>\n";
  1726.         }                
  1727.         if ( completed ) {
  1728.             outputStr +=  "    </del>\n";
  1729.         }        
  1730.         outputStr +=  "    </TD>\n";        
  1731.         
  1732.         outputStr +=  "    <TD>\n";
  1733.         if ( important ) {
  1734.             outputStr +=  "    <FONT color=\"FF0000\">\n";
  1735.         }    
  1736.         if ( completed ) {
  1737.             outputStr +=  "    <del>\n";
  1738.         }        
  1739.         outputStr +=  "      " ;
  1740.         if ( timeCellLabel == "" ) {
  1741.             timeCellLabel = " ";
  1742.         }        
  1743.         outputStr +=  timeCellLabel + '\n';
  1744.         if (important ) {
  1745.             outputStr +=  "    </FONT>\n";
  1746.         }        
  1747.         if ( completed ) {
  1748.             outputStr +=  "    </del>\n";
  1749.         }                
  1750.         outputStr +=  "    </TD>\n";                
  1751.         
  1752.         outputStr +=  "  </TR>\n";    
  1753.         
  1754.         // output notes if available
  1755.         // want to replace in notes: ("\n", "<BR/>") to get line breaks
  1756.             
  1757.          if ( todo != null  && todo.notes != null ) {         
  1758.             outputStr +=  "  <TR>\n";
  1759.             
  1760.             outputStr +=  "    <TD>\n";
  1761.             outputStr +=  "    </TD>\n";
  1762.             
  1763.             outputStr +=  "    <TD>\n";
  1764.  
  1765.             var notes = todo.notes;
  1766.             notes = notes.replace(new RegExp(/\n/g),"<BR/>");                      
  1767.             outputStr +=  "      " +notes;
  1768.             
  1769.             outputStr +=  "    </TD>\n";        
  1770.             
  1771.             outputStr +=  "    <TD>\n";
  1772.             outputStr +=  "    </TD>\n";
  1773.             
  1774.             outputStr +=  "    <TD>\n";
  1775.             outputStr +=  "    </TD>\n";            
  1776.             
  1777.             outputStr +=  "  </TR>\n";    
  1778.          }
  1779.         
  1780.     }    
  1781.  
  1782.     outputStr +=  " </TBODY>\n";
  1783.     outputStr +=  "</TABLE>\n";
  1784.     outputStr +=  "</BODY>\n";
  1785.     outputStr += "</div>\n";
  1786.     outputStr +=  "</HTML>\n";
  1787.     
  1788.  
  1789.     // now write file out to filesystem
  1790.     var file = reminderFox_getReminderViewAsHTMLFile();
  1791.     try {
  1792.         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  1793.     } catch (e) {
  1794.         alert("Permission to save file was denied.");
  1795.     }
  1796.  
  1797.     if ( file.exists() == false ) {
  1798.         file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 );
  1799.     }
  1800.  
  1801.     reminderFox_writeStringToFile(outputStr, file, true);
  1802.  
  1803.     var tempURL = "file:///" + file.path; 
  1804.     reminderFox_openURL(tempURL );    
  1805.     //file.remove(false);  // can't remove here as it can be removed before the browser opens (in Thunderbird case)
  1806. }
  1807.  
  1808.  
  1809. function createCalendarReminderArray() {
  1810.     var monthArray;
  1811.     var monthDay;    
  1812.     var dayReminderArray;    
  1813.     var newDayReminder;
  1814.     var  length;
  1815.     var val;
  1816.         
  1817.     calendarReminderArray = new Array(12); 
  1818.     var reminders = getCurrentReminderList();    
  1819.     
  1820.     var currentDate = oeDatePicker.gSelectedDate;
  1821.     if ( currentDate == null ) {
  1822.         currentDate = new Date();
  1823.     }
  1824.     var    year = currentDate.getFullYear();
  1825.     var dateSpan = getStartAndEndDates();
  1826.     var todaysDate = new Date();
  1827.     for( var i = 0; i < reminders.length; i++) {
  1828.         var basereminder = reminders[i];
  1829.         
  1830.         var allReminders = reminderFox_getAllRemindersInDateRange( basereminder,  dateSpan.start, dateSpan.end, false );
  1831.         var x;
  1832.         // maybe make this a method that returns start/endindex
  1833.         var startIndex = 0;
  1834.         var endIndex = 0;
  1835.         if ( allReminders.length > 0 ) {
  1836.             endIndex  = allReminders.length;
  1837.         }
  1838.         if ( allReminders.length > 0) {
  1839.             if ( SHOW_ALL_REMINDERS ) {
  1840.                 startIndex = 0;
  1841.                 endIndex = allReminders.length;
  1842.             }
  1843.             else if ( HIDE_ALL_REMINDERS ) {
  1844.                 for ( x = 0; x < allReminders.length; x++ ) {
  1845.                     if ( reminderFox_compareDates( allReminders[x].date, todaysDate) != -1 ) {
  1846.                         break;
  1847.                     }
  1848.                 }
  1849.                 // handle end case where x = length
  1850.                 startIndex = x;
  1851.         
  1852.                 // need to show reminders of yearly that have passed
  1853.                 if ( startIndex == allReminders.length ) {                
  1854.                     startIndex = allReminders.length -1;
  1855.                 }
  1856.                 endIndex = startIndex + 1;  
  1857.                 if ( endIndex > allReminders.length )  {
  1858.                     endIndex = allReminders.length;
  1859.                 }
  1860.             }
  1861.             // if there's only 1 reminder and the prefs are set to show prev/next, then just ignore the check
  1862.             else if ( !(allReminders.length == 1 && REPEAT_PREVIOUS_OCCURRENCES >= 1 &&  REPEAT_UPCOMING_OCCURRENCES >=1 ) )  {            
  1863.                 for ( x = 0; x < allReminders.length; x++ ) {
  1864.                     if ( reminderFox_compareDates( allReminders[x].date, todaysDate) != -1 ) {
  1865.                         break;
  1866.                     }
  1867.                 }
  1868.                 
  1869.                 if ( REPEAT_PREVIOUS_OCCURRENCES == -1 ) { 
  1870.                     startIndex = 0;
  1871.                 }
  1872.                 else {
  1873.                     startIndex = x - REPEAT_PREVIOUS_OCCURRENCES;
  1874.                     if ( startIndex < 0 ) {
  1875.                         startIndex = 0;
  1876.                     }
  1877.                 }
  1878.                 
  1879.                 if ( REPEAT_UPCOMING_OCCURRENCES == -1 ) {
  1880.                     endIndex = allReminders.length;
  1881.                 }
  1882.                 else {
  1883.                     endIndex = x + REPEAT_UPCOMING_OCCURRENCES;
  1884.                     if ( endIndex > allReminders.length ) {
  1885.                         endIndex = allReminders.length;
  1886.                     }
  1887.                 }
  1888.                 
  1889.                 // if the user is showing no previous occurrences, we still want to show if a previous reminder is marked as RUC
  1890.                 if ( REPEAT_PREVIOUS_OCCURRENCES == 0 && 
  1891.                     basereminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED ) {
  1892.                     if ( startIndex > 0  && startIndex == endIndex  ) { // eminderFox_compareDates( allReminders[x].date, todaysDate) == 1 ) {
  1893.                         startIndex = startIndex - 1;                                                        
  1894.                     }                    
  1895.                 }                                
  1896.              }
  1897.         }
  1898.        for (  var j = startIndex; j < endIndex; j++ ) {        
  1899.             var reminder = allReminders[j];        
  1900.             reminder = reminderFox_processReminderDescription(reminder,  dateSpan.start.getFullYear(), false);    
  1901.             
  1902.             // if it's marked as RemindUntilComplete, this should be treated as Today's date            
  1903.              if ( reminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED && j == startIndex ) {
  1904.                  var todaysDate = new Date();
  1905.                  if (  todaysDate.getFullYear() == year ) {   // only valid for current year in the calendar
  1906.                      var ignore = false;
  1907.                      var displayList = document.getElementById("displayType");    
  1908.                     if ( displayList != null ) {    
  1909.                         var displayListIndex = displayList.selectedIndex;
  1910.                         // month or week
  1911.                         if ( displayListIndex == 1 || displayListIndex == 2 ) {
  1912.                             // if the date is outside of the selected month/week, then just show it.
  1913.                             // Otherwise, go ahead and show it as Today's date.                            
  1914.                             if ( !( reminderFox_compareDates( todaysDate, dateSpan.start) > -1 &&
  1915.                                 reminderFox_compareDates( todaysDate, dateSpan.end) < 1 ) ) {
  1916.                                 ignore = true;
  1917.                             }
  1918.                         }
  1919.                     }
  1920.                     if ( !ignore ) {
  1921.                          reminder = reminderFox_cloneReminderFoxEvent(reminder);             
  1922.                         reminder.date  = new Date( todaysDate.getFullYear(), todaysDate.getMonth(), todaysDate.getDate(), 
  1923.                                      reminder.date.getHours(), reminder.date.getMinutes() );        
  1924.                     }
  1925.                  }
  1926.              }             
  1927.     
  1928.             monthArray = calendarReminderArray[reminder.date.getMonth()];
  1929.             if ( monthArray == null ) {
  1930.                 monthArray = new Array(31);
  1931.                 calendarReminderArray[reminder.date.getMonth()] = monthArray;
  1932.             }
  1933.                 
  1934.             monthDay = reminder.date.getDate();
  1935.             dayReminderArray = monthArray[monthDay - 1];
  1936.             if ( dayReminderArray == null ) {
  1937.                 dayReminderArray = new Array();
  1938.                 monthArray[monthDay - 1] = dayReminderArray;
  1939.             }
  1940.             length = dayReminderArray.length;
  1941.             
  1942.             var ignoreReminder = false;
  1943.             if (HIDE_COMPLETED_ITEMS &&
  1944.                  reminderFox_isCompletedForDate( reminder, reminder.date) )  {
  1945.                 ignoreReminder = true;                
  1946.             }
  1947.             if ( !ignoreReminder ) {
  1948.                 dayReminderArray[length] = reminder;
  1949.             }
  1950.         }
  1951.     }
  1952. }
  1953.  
  1954.  
  1955.  
  1956. function createCalendarTodoArrayFiltered() {
  1957.     var monthArray;
  1958.     var monthDay;    
  1959.     var dayReminderArray;    
  1960.     var newDayReminder;
  1961.     var  length;
  1962.     var val;
  1963.         
  1964.     calendarTodoArray = new Array(12);  
  1965.  
  1966.     var reminders = getCurrentTodoList();    
  1967.     
  1968.     var currentDate = oeDatePicker.gSelectedDate;
  1969.     if ( currentDate == null ) {
  1970.         currentDate = new Date();
  1971.     }
  1972.     var    year = currentDate.getFullYear();
  1973.     var dateSpan = getStartAndEndDates();
  1974.     var todaysDate = new Date();
  1975.     for( var i = 0; i < reminders.length; i++) {
  1976.         var basereminder = reminders[i];
  1977.         if ( basereminder.date == null ) { 
  1978.             continue;  // if there is no date set on this todo, then ignore it
  1979.         }
  1980.         
  1981.         var allTodos = reminderFox_getAllRemindersInDateRange( basereminder,  dateSpan.start, dateSpan.end, false );
  1982.         var x;
  1983.         // maybe make this a method that returns start/endindex
  1984.         var startIndex = 0;
  1985.         var endIndex = 0;
  1986.         if ( allTodos.length > 0 ) {
  1987.             endIndex  = allTodos.length;
  1988.         }
  1989.         if ( allTodos.length > 0) {
  1990.             if ( SHOW_ALL_REMINDERS ) {
  1991.                 startIndex = 0;
  1992.                 endIndex = allTodos.length;
  1993.             }
  1994.             else if ( HIDE_ALL_REMINDERS ) {
  1995.                 for ( x = 0; x < allTodos.length; x++ ) {
  1996.                     if ( reminderFox_compareDates( allTodos[x].date, todaysDate) != -1 ) {
  1997.                         break;
  1998.                     }
  1999.                 }
  2000.                 // handle end case where x = length
  2001.                 startIndex = x;
  2002.         
  2003.                 // need to show reminders of yearly that have passed
  2004.                 if ( startIndex == allTodos.length ) {                
  2005.                     startIndex = allTodos.length -1;
  2006.                 }
  2007.                 endIndex = startIndex + 1;  
  2008.                 if ( endIndex > allTodos.length )  {
  2009.                     endIndex = allTodos.length;
  2010.                 }
  2011.             }
  2012.             // if there's only 1 reminder and the prefs are set to show prev/next, then just ignore the check
  2013.             else if ( !(allTodos.length == 1 && REPEAT_PREVIOUS_OCCURRENCES >= 1 &&  REPEAT_UPCOMING_OCCURRENCES >=1 ) )  {            
  2014.                 for ( x = 0; x < allTodos.length; x++ ) {
  2015.                     if ( reminderFox_compareDates( allTodos[x].date, todaysDate) != -1 ) {
  2016.                         break;
  2017.                     }
  2018.                 }
  2019.                 
  2020.                 if ( REPEAT_PREVIOUS_OCCURRENCES == -1 ) { 
  2021.                     startIndex = 0;
  2022.                 }
  2023.                 else {
  2024.                     startIndex = x - REPEAT_PREVIOUS_OCCURRENCES;
  2025.                     if ( startIndex < 0 ) {
  2026.                         startIndex = 0;
  2027.                     }
  2028.                 }
  2029.                 
  2030.                 if ( REPEAT_UPCOMING_OCCURRENCES == -1 ) {
  2031.                     endIndex = allTodos.length;
  2032.                 }
  2033.                 else {
  2034.                     endIndex = x + REPEAT_UPCOMING_OCCURRENCES;
  2035.                     if ( endIndex > allTodos.length ) {
  2036.                         endIndex = allTodos.length;
  2037.                     }
  2038.                 }                            
  2039.              }
  2040.         }
  2041.        for (  var j = startIndex; j < endIndex; j++ ) {        
  2042.             var todo = allTodos[j];            
  2043.             todo = reminderFox_processReminderDescription(todo, dateSpan.start.getFullYear(), false);    
  2044.                 
  2045.             monthArray = calendarTodoArray[todo.date.getMonth()];
  2046.             if ( monthArray == null ) {
  2047.                 monthArray = new Array(31);
  2048.                 calendarTodoArray[todo.date.getMonth()] = monthArray;
  2049.             }
  2050.                 
  2051.             monthDay = todo.date.getDate();
  2052.             dayReminderArray = monthArray[monthDay - 1];
  2053.             if ( dayReminderArray == null ) {
  2054.                 dayReminderArray = new Array();
  2055.                 monthArray[monthDay - 1] = dayReminderArray;
  2056.             }
  2057.             length = dayReminderArray.length;
  2058.             
  2059.             var ignoreReminder = false;            
  2060.             if (HIDE_COMPLETED_ITEMS &&
  2061.                          todo.completedDate != null ) { 
  2062.                     ignoreReminder = true;            
  2063.             }
  2064.     
  2065.             if ( !ignoreReminder ) {
  2066.                 dayReminderArray[length] = todo;
  2067.             }            
  2068.         }
  2069.     }
  2070. }
  2071.  
  2072.  
  2073. function createCalendarTodoArray() {
  2074.     // if filtered, then get the individual repeat instances...
  2075.     var filterIndex = getDisplayIndex();
  2076.     if ( filterIndex > 0 ) {
  2077.         createCalendarTodoArrayFiltered();
  2078.         return;
  2079.     }
  2080.     
  2081.     
  2082.     var monthArray;
  2083.     var monthDay;    
  2084.     var dayReminderArray;    
  2085.     var newDayReminder;
  2086.     var  length;
  2087.     var val;
  2088.  
  2089.     calendarTodoArray = new Array(12);  
  2090.  
  2091.     var dateSpan = getStartAndEndDates();
  2092.     var allTodos = reminderFox_getAllTodosInDateRangeForGivenList(getCurrentTodoList(),   dateSpan.start, dateSpan.end );
  2093.     
  2094.    for (  var j = 0; j < allTodos.length; j++ ) {        
  2095.         var todo = allTodos[j];            
  2096.         todo = reminderFox_processReminderDescription(todo, dateSpan.start.getFullYear(), false);    
  2097.             
  2098.         monthArray = calendarTodoArray[todo.date.getMonth()];
  2099.         if ( monthArray == null ) {
  2100.             monthArray = new Array(31);
  2101.             calendarTodoArray[todo.date.getMonth()] = monthArray;
  2102.         }
  2103.             
  2104.         monthDay = todo.date.getDate();
  2105.         dayReminderArray = monthArray[monthDay - 1];
  2106.         if ( dayReminderArray == null ) {
  2107.             dayReminderArray = new Array();
  2108.             monthArray[monthDay - 1] = dayReminderArray;
  2109.         }
  2110.         length = dayReminderArray.length;
  2111.         
  2112.         var ignoreReminder = false;            
  2113.         if (HIDE_COMPLETED_ITEMS &&
  2114.                      todo.completedDate != null ) { 
  2115.                 ignoreReminder = true;            
  2116.         }
  2117.  
  2118.         if ( !ignoreReminder ) {
  2119.             dayReminderArray[length] = todo;
  2120.         }        
  2121.     }
  2122. }
  2123.  
  2124.  
  2125. function reminderFox_getAddTimeString( reminder ) {
  2126.     var timeString = null;
  2127.     if ( !reminder.allDayEvent ) {
  2128.         try {
  2129.             var hours = reminder.date.getHours();
  2130.             
  2131.             var AMorPM = REMINDER_FOX_PM;                
  2132.             var use24HourTime;
  2133.             try {
  2134.                 use24HourTime = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_USE_24_HOUR_TIME);
  2135.             } catch(e) {
  2136.             }                
  2137.             if (  use24HourTime ) {
  2138.                 AMorPM = "";
  2139.                 if ( hours < 10 ) {
  2140.                     hours = "0" + hours;
  2141.                 }
  2142.         
  2143.             }        
  2144.         
  2145.             if ( AMorPM != "" ) {
  2146.                 if ( hours < 12 ) {
  2147.                     AMorPM = REMINDER_FOX_AM;
  2148.                 }
  2149.                 if ( hours == 0 ) {
  2150.                     hours = 12;
  2151.                 }
  2152.                 if ( hours >= 13 ) {
  2153.                     hours = hours -12;
  2154.                 }    
  2155.             }            
  2156.  
  2157.             var minutes = reminder.date.getMinutes();
  2158.             if ( minutes < 10 ) {
  2159.                 minutes = "0" + minutes;
  2160.             }
  2161.                             
  2162.             timeString = hours + REMINDER_FOX_TIME_DELIMITER + minutes;
  2163.             if ( AMorPM != "" ) {
  2164.                 timeString = timeString + " " + AMorPM;        
  2165.             }
  2166.         }
  2167.         catch ( e ) { 
  2168.         }
  2169.     }    
  2170.     return timeString;
  2171. }
  2172.  
  2173. function setRemindUntilCompleteColumn( reminder, columnLabel ) {
  2174.          if ( reminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED ) {
  2175.               columnLabel.setAttribute("src",REMINDER_FOX_REMIND_UNTIL_COMPLETED_TO_BE_MARKED_IMAGE);    
  2176.          }
  2177.          else  if ( reminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED ) {
  2178.               columnLabel.setAttribute("src",REMINDER_FOX_REMIND_UNTIL_COMPLETED_IMAGE);
  2179.          }
  2180. }
  2181.  
  2182.  
  2183.  
  2184.  
  2185. function getTimeHoursFromString(time) {
  2186.     var hours = 0;
  2187.     var startindex = time.indexOf(g_reminderFoxBundle.getString("rf.add.time.delimiter") ); 
  2188.     if ( startindex != -1 ) {
  2189.         try {
  2190.             var hours = parseInt(time.substring(0, startindex ));
  2191.             var minutes =  time.substring(startindex+1, startindex + 3);
  2192.             // now trim remainder
  2193.             var remainder = time.substring( startindex + 3, time.length );
  2194.             if ( remainder != "" ) {
  2195.                 remainder = reminderFox_trim( remainder );
  2196.                 var AMorPM = remainder;
  2197.                 if ( AMorPM.toUpperCase() == REMINDER_FOX_PM.toUpperCase() ) {
  2198.                     if ( hours != 12 ) {
  2199.                         hours = hours+12;
  2200.                     }
  2201.                 }
  2202.                 else { 
  2203.                     if ( hours == 12 ) {
  2204.                         hours = 0;
  2205.                     }
  2206.                 }
  2207.             }
  2208.         }
  2209.         catch ( e ) {
  2210.         }
  2211.     }
  2212.     return hours;
  2213. }
  2214.  
  2215. function getTimeMinutesFromString(time) {
  2216.     var minutes = 0;
  2217.     var startindex = time.indexOf(g_reminderFoxBundle.getString("rf.add.time.delimiter") ); 
  2218.     if ( startindex != -1 ) {
  2219.         try {
  2220.              minutes =  time.substring(startindex+1, startindex + 3);
  2221.         }
  2222.         catch ( e ) {
  2223.         }
  2224.     }
  2225.     return minutes;
  2226. }
  2227.  
  2228.  
  2229. function reminderFox_getDateVariableString(reminder, date )  {
  2230.     return reminderFox_getDateVariable( reminder, date, dateVariableString );
  2231. }
  2232.  
  2233. /**
  2234.  * 'View'
  2235.  *<br>     'getStartAndEndDates' has been modified to use also with 'View'.
  2236.  *<br>     calling parameters:
  2237.  *<br>         displayListIndex :: day-periode, same as with getDisplayIndex()
  2238.  *<br>         useToday ::        true== use 'TODAY' for start day of selected 'day-periode'
  2239.  *<br> 
  2240.  *<br>     Note:  rearranging/adding the XUL items and a re-numbering has to be changed
  2241.  *<br>             also with 'VIEW'  (rmFxViews.js) 
  2242.  */
  2243. function getStartAndEndDates(displayListIndex, useToday, showAll) {
  2244.     var startAndEnd = { start: null, end: null };  
  2245.     
  2246.     //var showAll = false;
  2247.     if ( showAll ) {  // if showAll is true, we will show ALL reminders instead of just this year/month/week/etc
  2248.         // get all years (we'll just do +/- 150 to put some cap and aid performance)
  2249.         var currentyear = new Date().getFullYear();
  2250.         startAndEnd.start = new Date( currentyear - 150, 0, 1 );  // start of year
  2251.         startAndEnd.end  = new Date( currentyear + 150, 11, 31 );  // end of year
  2252.         return startAndEnd;
  2253.     }
  2254.     
  2255.  
  2256.  
  2257.     var year;
  2258.     var month;
  2259.     var day;
  2260.     if ( oeDatePicker.gSelectedDate != null ) {
  2261.         year = oeDatePicker.gSelectedDate.getFullYear();
  2262.         month = oeDatePicker.gSelectedDate.getMonth();
  2263.         day = oeDatePicker.gSelectedDate.getDate();
  2264.     }
  2265.     if ( year == null ) {
  2266.         year = new Date().getFullYear();
  2267.         month = new Date().getMonth();
  2268.         day = new Date().getDate();
  2269.         
  2270.     }     
  2271.         
  2272.  
  2273.     // var displayListIndex = getDisplayIndex();
  2274.     
  2275. // gWVIEW    <<--
  2276. //    var displayListIndex = getDisplayIndex();
  2277.     if (displayListIndex == null) {
  2278.         displayListIndex = getDisplayIndex();
  2279.     }
  2280.     if (useToday == true) {
  2281.         year = new Date().getFullYear();
  2282.         month = new Date().getMonth();
  2283.         day = new Date().getDate();
  2284.     }
  2285. // gWVIEW  -->>    
  2286.     
  2287.     // year
  2288.     if ( displayListIndex == 0 ) {
  2289.         startAndEnd.start = new Date( year, 0, 1 );  // start of year
  2290.         startAndEnd.end  = new Date( year, 11, 31 );  // end of year
  2291.     }
  2292.     // month
  2293.     else if ( displayListIndex == 1 ) {
  2294.         var endDay = reminderFox_getValidDateForMonth( year, month, 31 );
  2295.         startAndEnd.start = new Date( year, month, 1 );  // start of year
  2296.         startAndEnd.end  = new Date( year, month, endDay );  // end of year
  2297.     }
  2298.     // week
  2299.     else if ( displayListIndex == 2 ) {
  2300.         // get start of the week
  2301.         var start = new Date( year, month, day );             
  2302.         startAndEnd.start = reminderFox_getThisDayFromCurrentDate( start, 0);    
  2303.         
  2304.         // get end of the week
  2305.         var end = new Date( year, month, day );
  2306.         startAndEnd.end  = reminderFox_getThisDayFromCurrentDate( end, 6);
  2307.         
  2308.         // if the start date is before this year, just use this year as start
  2309.         var startOfYear = new Date( year, 0, 1 );  // start of year
  2310.         if ( reminderFox_compareDates( startAndEnd.start, startOfYear) == -1 ) {
  2311.             startAndEnd.start = startOfYear;
  2312.         }
  2313.         // if the end date goes beyond this year, use the end of year as the stopping point
  2314.         var endOfYear =  new Date( year, 11, 31 );  // end of year
  2315.         if ( reminderFox_compareDates( startAndEnd.end, endOfYear) == 1 ) {
  2316.             startAndEnd.end = endOfYear;
  2317.         }
  2318.     }
  2319.     // day
  2320.     else if ( displayListIndex == 3 ) {
  2321.         startAndEnd.start = new Date( year, month, day );  // start of year
  2322.         startAndEnd.end  = new Date( year, month, day );  // end of year
  2323.     }
  2324.     // next week
  2325.     else if ( displayListIndex == 4 ) {
  2326.         var todaysDate = new Date();
  2327.         startAndEnd.start = todaysDate;
  2328.         startAndEnd.end  = new Date( todaysDate.getFullYear(), todaysDate.getMonth(), todaysDate.getDate() + 7 );  // end 7 days from now
  2329.         
  2330.         // if the end date goes beyond this year, use the end of year as the stopping point
  2331.         var endOfYear =  new Date( year, 11, 31 );  // end of year
  2332.         if ( reminderFox_compareDates( startAndEnd.end, endOfYear) == 1 ) {
  2333.             startAndEnd.end = endOfYear;
  2334.         }
  2335.         
  2336.     }
  2337.     // next two weeks
  2338.     else if ( displayListIndex == 5 ) {            
  2339.         var todaysDate = new Date();
  2340.         startAndEnd.start = todaysDate;
  2341.         startAndEnd.end  = new Date( todaysDate.getFullYear(), todaysDate.getMonth(), todaysDate.getDate() + 14 );  // end 7 days from now
  2342.         
  2343.         // if the end date goes beyond this year, use the end of year as the stopping point
  2344.         var endOfYear =  new Date( year, 11, 31 );  // end of year
  2345.         if ( reminderFox_compareDates( startAndEnd.end, endOfYear) == 1 ) {
  2346.             startAndEnd.end = endOfYear;
  2347.         }
  2348.     }
  2349.     
  2350.     if ( startAndEnd.start == null ) {
  2351.         startAndEnd.start = new Date( year, 0, 1 );  // start of year
  2352.         startAndEnd.end  = new Date( year, 11, 31 );  // end of year
  2353.     }
  2354.     return startAndEnd;
  2355. }
  2356.  
  2357. function createListItem(baseReminder) {
  2358.     var lastListIndex = 0;
  2359.     var once = document.getElementById("occurrence");
  2360.     var treeChildren = document.getElementById("treechildren");
  2361.     
  2362.     var dateSpan = getStartAndEndDates();
  2363.     var year;
  2364.     if ( oeDatePicker.gSelectedDate != null ) {
  2365.         year = oeDatePicker.gSelectedDate.getFullYear();
  2366.     }
  2367.     if ( year == null ) {
  2368.         year = new Date().getFullYear();
  2369.     }     
  2370.     var todaysDate = new Date();
  2371.     var allReminders = reminderFox_getAllRemindersInDateRange( baseReminder,  dateSpan.start, dateSpan.end, false );
  2372.     
  2373.     var startIndex = 0;
  2374.     var endIndex = 0;
  2375.     if ( allReminders.length > 0 ) {
  2376.         endIndex  = allReminders.length;
  2377.     }
  2378.     if ( allReminders.length > 0) {
  2379.         if ( SHOW_ALL_REMINDERS ) {
  2380.             startIndex = 0;
  2381.             endIndex = allReminders.length;
  2382.         }
  2383.         else if ( HIDE_ALL_REMINDERS ) {
  2384.             for ( var x = 0; x < allReminders.length; x++ ) {
  2385.                 if ( reminderFox_compareDates( allReminders[x].date, todaysDate) != -1 ) {
  2386.                     break;
  2387.                 }
  2388.             }
  2389.             startIndex = x;    
  2390.             // need to show reminders of yearly that have passed
  2391.             if ( startIndex == allReminders.length ) {                
  2392.                 startIndex = allReminders.length -1;
  2393.             }
  2394.         }
  2395.  
  2396.         // if there's only 1 reminder and the prefs are set to show prev/next, then just ignore the check
  2397.         else if ( !(allReminders.length == 1 && REPEAT_PREVIOUS_OCCURRENCES >= 1 &&  REPEAT_UPCOMING_OCCURRENCES >=1 ) )  {            
  2398.             for ( var x = 0; x < allReminders.length; x++ ) {
  2399.                 if ( reminderFox_compareDates( allReminders[x].date, todaysDate) != -1 ) {
  2400.                     break;
  2401.  
  2402.                 }
  2403.             }
  2404.             if ( REPEAT_PREVIOUS_OCCURRENCES == -1 ) {
  2405.                 startIndex = 0;
  2406.             }
  2407.             else {
  2408.                 startIndex = x - REPEAT_PREVIOUS_OCCURRENCES;
  2409.                 if ( startIndex < 0 ) {
  2410.                     startIndex = 0;
  2411.                 }
  2412.             }
  2413.             
  2414.             if ( REPEAT_UPCOMING_OCCURRENCES == -1 ) {
  2415.                 endIndex = allReminders.length;
  2416.             }
  2417.             else {
  2418.                 endIndex = x + REPEAT_UPCOMING_OCCURRENCES;
  2419.                 if ( endIndex > allReminders.length ) {
  2420.                     endIndex = allReminders.length;
  2421.                 }
  2422.             }
  2423.          }
  2424.     }
  2425.       
  2426.    for (  var j = startIndex; j < endIndex; j++ ) {            
  2427.         var treeSelection;
  2428.         var value ;
  2429.         var tree;    
  2430.         var boxobject;
  2431.         var first;
  2432.         var last;
  2433.         var previousReminderOffset ;        
  2434.  
  2435.         var newItem = document.createElement("treeitem");
  2436.         var newRow = document.createElement("treerow");
  2437.         newRow.setAttribute( REMINDER_ID_REF, baseReminder.id );
  2438.         var newDateLabel = document.createElement("treecell");
  2439.         var newDescLabel = document.createElement("treecell");
  2440.         
  2441.         newItem.appendChild(newRow);
  2442.         newRow.appendChild(newDateLabel);
  2443.         newRow.appendChild(newDescLabel);
  2444.         var isImportant = false;    
  2445.         
  2446.         var reminder = allReminders[j];        
  2447.         reminder = reminderFox_processReminderDescription(reminder, year, false);        
  2448.         
  2449.         // if it's marked as RemindUntilComplete, this should be treated as Today's date
  2450.          if ( reminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED && j == startIndex ) {
  2451.              if (  todaysDate.getFullYear() == year ) {   // only valid for current year in the calendar
  2452.                  // if the Filter is applied, don't show as today's date if it's another selected month/week
  2453.                  var ignore = false;
  2454.              
  2455.                 var displayListIndex = getDisplayIndex();
  2456.                 // month or week
  2457.                 if ( displayListIndex == 1 || displayListIndex == 2 ) {
  2458.                     // if the date is outside of the selected month/week, then just show it.
  2459.                     // Otherwise, go ahead and show it as Today's date.                            
  2460.                     if ( !( reminderFox_compareDates( todaysDate, dateSpan.start) > -1 &&
  2461.                         reminderFox_compareDates( todaysDate, dateSpan.end) < 1 ) ) {
  2462.                         ignore = true;
  2463.                     }
  2464.                 }
  2465.                 if ( !ignore ) {
  2466.                      reminder = reminderFox_cloneReminderFoxEvent(reminder);
  2467.                     reminder.date  = new Date( todaysDate.getFullYear(), todaysDate.getMonth(), todaysDate.getDate(), 
  2468.                              reminder.date.getHours(), reminder.date.getMinutes() );    
  2469.                 }
  2470.                 
  2471.             }
  2472.          }
  2473.     
  2474.         var dayVal = reminder.date.getDate();
  2475.         var monthArray = calendarReminderArray[reminder.date.getMonth()];
  2476.         if ( monthArray == null ) {
  2477.             monthArray = new Array(31);
  2478.             calendarReminderArray[reminder.date.getMonth()] = monthArray;
  2479.         }
  2480.     
  2481.         var dayReminderArray = monthArray[dayVal - 1];
  2482.         if ( dayReminderArray == null ) {
  2483.             dayReminderArray = new Array();
  2484.             monthArray[dayVal - 1] = dayReminderArray;
  2485.         }
  2486.  
  2487.         var  length = dayReminderArray.length;
  2488.         dayReminderArray[length] = reminder;
  2489.  
  2490.         if ( useDefaultDate ) {
  2491.             var monthAsText = reminderFox_getMonthAsText(reminder.date.getMonth());        
  2492.             newDateLabel.setAttribute("label", monthAsText + " " + dayVal);
  2493.         }
  2494.         else {
  2495.             newDateLabel.setAttribute("label", reminderFox_getDateVariableString( reminder, reminder.date) );
  2496.         }
  2497.         newRow.setAttribute( REMINDER_DATE_REF, reminder.date.getTime() );
  2498.         
  2499.         newDescLabel.setAttribute("label", reminder.summary);    
  2500.         var newTimeLabel = document.createElement("treecell");
  2501.         newRow.appendChild(newTimeLabel);        
  2502.         
  2503.         var newCompletedDateLabel = document.createElement("treecell");
  2504.         newRow.appendChild(newCompletedDateLabel);                
  2505.         
  2506.         var newRepeatLabel = document.createElement("treecell");
  2507.         newRow.appendChild(newRepeatLabel);
  2508.         
  2509.         var newCompleteLabel = document.createElement("treecell");
  2510.         newRow.appendChild(newCompleteLabel);
  2511.         
  2512.         var newRemindUntilCompletedLabel = document.createElement("treecell");
  2513.         newRow.appendChild(newRemindUntilCompletedLabel);
  2514.         
  2515.         var newNotesLabel = document.createElement("treecell");
  2516.         newRow.appendChild(newNotesLabel);    
  2517.         
  2518.         var alarmLabel = document.createElement("treecell");
  2519.         newRow.appendChild(alarmLabel);        
  2520.         
  2521.         var categoriesLabel = document.createElement("treecell");
  2522.         newRow.appendChild(categoriesLabel);            
  2523.         
  2524.         var endDateLabel = document.createElement("treecell");
  2525.         newRow.appendChild(endDateLabel);        
  2526.     
  2527.          var isToday = reminderFox_compareDates( reminder.date, todaysDate) == 0 ;
  2528.          var isImportant = reminder.priority == REMINDER_PRIORITY_IMPORTANT;
  2529.          var isCompleted =  reminderFox_isCompletedForDate( reminder, reminder.date);
  2530.          
  2531.         setTextProperties( isToday, isImportant, isCompleted, newDateLabel, newDescLabel, newTimeLabel );             
  2532.              
  2533.          if (isCompleted )  {
  2534.              newCompleteLabel.setAttribute("src",REMINDER_FOX_COMPLETED_IMAGE);        
  2535.  
  2536.             if ( useDefaultDate ) {
  2537.                 var monthAsText = reminderFox_getMonthAsText(reminder.completedDate.getMonth());        
  2538.                 newCompletedDateLabel.setAttribute("label", monthAsText + " " + reminder.completedDate.getDate());
  2539.             }
  2540.             else {
  2541.                 newCompletedDateLabel.setAttribute("label", reminderFox_getDateVariableString( reminder, reminder.completedDate ) );
  2542.             }
  2543.         }
  2544.         
  2545.         
  2546.         if ( reminder.endDate != null ) {
  2547.             var myEndDate = new Date( reminder.date.getTime() + reminder.durationTime );
  2548.             if ( reminder.allDayEvent ) {
  2549.                 myEndDate.setDate( myEndDate.getDate() -1 ); // all-day offset
  2550.             }
  2551.             if ( useDefaultDate ) {
  2552.                 var monthAsText = reminderFox_getMonthAsText(myEndDate.getMonth());        
  2553.                 endDateLabel.setAttribute("label", monthAsText + " " + myEndDate.getDate());
  2554.             }
  2555.             else {
  2556.                 endDateLabel.setAttribute("label", reminderFox_getDateVariableString( reminder, myEndDate ) );
  2557.             }
  2558.         }
  2559.          
  2560.          setRemindUntilCompleteColumn( reminder, newRemindUntilCompletedLabel );
  2561.  
  2562.  
  2563.         if ( reminder.allDayEvent ) {
  2564.             newTimeLabel.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  2565.         }
  2566.         else {
  2567.             var time = reminderFox_getAddTimeString(reminder);
  2568.             if ( time == null ) {
  2569.                 newTimeLabel.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  2570.             }
  2571.             else {            
  2572.                 newTimeLabel.setAttribute("label", time);
  2573.             }
  2574.         }
  2575.         
  2576.         if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) {
  2577.             newRepeatLabel.setAttribute("label", REPEAT_LABEL_YEARLY);
  2578.         }
  2579.         else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) {
  2580.             newRepeatLabel.setAttribute("label", REPEAT_LABEL_YEARLY_DAY);
  2581.         }        
  2582.         else     if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
  2583.             newRepeatLabel.setAttribute("label", REPEAT_LABEL_MONTHLY);
  2584.         }
  2585.         else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {
  2586.             newRepeatLabel.setAttribute("label", REPEAT_LABEL_MONTHLY_DAY);
  2587.         }
  2588.         else    if ( reminder.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {        
  2589.             newRepeatLabel.setAttribute("label", REPEAT_LABEL_WEEKLY);
  2590.         }
  2591.         else    if ( reminder.recurrence.type  == REMINDER_RECURRENCE_DAILY ) {        
  2592.              newRepeatLabel.setAttribute("label", REPEAT_LABEL_DAILY);
  2593.         }                    
  2594.         else {        
  2595.             newRepeatLabel.setAttribute("label", REPEAT_LABEL_NONE);
  2596.         }        
  2597.         
  2598.           if ( reminder.notes != null ) {
  2599.              newNotesLabel.setAttribute("src",REMINDER_FOX_NOTES_IMAGE);            
  2600.          }     
  2601.          
  2602.           if ( reminder.alarm != null ) {
  2603.               
  2604.               // actually could check if snooze time is less than reminder's date...  if so don't show it (the snooze has passed?)
  2605.               if ( reminder.snoozeTime != null && !isCompleted ) { 
  2606.                   alarmLabel.setAttribute("src",REMINDER_FOX_ALARM_SNOOZE_IMAGE);        
  2607.               }
  2608.               else {
  2609.                  alarmLabel.setAttribute("src",REMINDER_FOX_ALARM_IMAGE);            
  2610.               }
  2611.          }             
  2612.                   
  2613.          if ( reminder.categories != null ) {
  2614.              categoriesLabel.setAttribute("label", reminder.categories);
  2615.              // TODO:
  2616.              //newDescLabel.setAttribute( "style", "color: #F6F9ED" );
  2617.          }
  2618.          
  2619.          if ( reminder.messageID != null ) {
  2620.              var newMailLabel = document.createElement("treecell");
  2621.             newRow.appendChild(newMailLabel);    
  2622.              newMailLabel.setAttribute("src",REMINDER_FOX_MAIL_IMAGE);            
  2623.          }
  2624.          
  2625.    
  2626.          
  2627.         // Figure out where to put the new item in sorted list
  2628.         var treeitems = treeChildren.childNodes;
  2629.         var added = false;
  2630.         
  2631.         for (var i=lastListIndex; i < treeitems.length; i++) {
  2632.             var item = treeitems[i];
  2633.             var row = item.childNodes[0];
  2634.             var reminderDateTime = row.getAttribute(REMINDER_DATE_REF);    
  2635.             var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  2636.             
  2637.             var timeLabel = row.childNodes[2].getAttribute("label");            
  2638.             var allDay = timeLabel == REMINDER_FOX_TIME_ALL_DAY_LABEL;
  2639.             
  2640.             if (reminderInstanceDate.getMonth() > reminder.date.getMonth() || (reminderInstanceDate.getMonth() == reminder.date.getMonth() && dayVal <= reminderInstanceDate.getDate() ) ) {    
  2641.                 if (reminderInstanceDate.getMonth() == reminder.date.getMonth() && reminderInstanceDate.getDate() == dayVal) {
  2642.                     if ( reminder.allDayEvent && !allDay ) {
  2643.                         continue;
  2644.                     }
  2645.                     else if ( !reminder.allDayEvent && allDay ) {
  2646.                         // adding hourly reminder; let's add it
  2647.                     }
  2648.                     else if ( !reminder.allDayEvent && !allDay ) {
  2649.                         // two hourly events.  Let's compare the times.
  2650.                         var currentHours = getTimeHoursFromString(timeLabel);
  2651.                         var currentMinutes = getTimeMinutesFromString(timeLabel);
  2652.                         if ( reminder.date.getHours() > currentHours ) {
  2653.                             continue;
  2654.                         }
  2655.                         else if ( reminder.date.getHours() == currentHours &&
  2656.                             reminder.date.getMinutes() > currentMinutes ) {
  2657.                                 continue;
  2658.                         }
  2659.                     }
  2660.                     else if ( !isImportant ) {
  2661.                         // if this reminder is not marked as important, add to the 
  2662.                         // end of the list of today's reminders
  2663.                         continue;
  2664.                     }
  2665.                 }
  2666.                 treeChildren.insertBefore(newItem, item);
  2667.                 added = true;
  2668.             
  2669.                 // highlight the newly added reminder in the list
  2670.                 treeSelection = document.getElementById("reminderTree").view.selection;    
  2671.                 if ( selectCalendarSync ) {
  2672.                         try { 
  2673.                             treeSelection.select(i);
  2674.                         } 
  2675.                         catch ( e ) {
  2676.                         }
  2677.                         // make sure that newly selected row is shown in scroll pane
  2678.                         value = document.getElementById("treeparent").value;
  2679.                         tree = document.getElementById("reminderTree");                    
  2680.                         boxobject = tree.boxObject;
  2681.                         boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  2682.                         
  2683.                         first = boxobject.getFirstVisibleRow();
  2684.                         last = boxobject.getLastVisibleRow();
  2685.                         if ( i < first || i > last ) {    
  2686.                             boxobject.scrollToRow(treeitems.length - 1);
  2687.                             boxobject.scrollToRow(treeitems.length - 9);
  2688.                         }
  2689.                                             
  2690.                         previousReminderOffset = 3;
  2691.                         if ( i < previousReminderOffset ) { 
  2692.                             boxobject.ensureRowIsVisible(i);
  2693.                         }
  2694.                         else {
  2695.                             boxobject.ensureRowIsVisible(i  - previousReminderOffset);
  2696.                         }                        
  2697.                 }
  2698.                 lastListIndex = i;
  2699.                 break;
  2700.             }
  2701.         }
  2702.             
  2703.         if (!added){        
  2704.             treeChildren.appendChild(newItem);
  2705.             // highlight the newly added reminder in the list
  2706.             treeSelection = document.getElementById("reminderTree").view.selection;    
  2707.             if ( selectCalendarSync ) {
  2708.                 treeSelection.select(treeitems.length - 1);
  2709.                 // make sure that newly selected row is shown in scroll pane
  2710.                 value = document.getElementById("treeparent").value;
  2711.                 tree = document.getElementById("reminderTree");                    
  2712.                 boxobject = tree.boxObject;
  2713.                 boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  2714.                 
  2715.                 first = boxobject.getFirstVisibleRow();
  2716.                 last = boxobject.getLastVisibleRow();
  2717.                 if ( i < first || i > last ) {    
  2718.                     boxobject.scrollToRow(treeitems.length - 1);            
  2719.                     boxobject.scrollToRow(treeitems.length - 9);
  2720.                 }
  2721.                 
  2722.                 previousReminderOffset = 3;
  2723.                 if ( i < previousReminderOffset ) { 
  2724.                     boxobject.ensureRowIsVisible(i);
  2725.                 }
  2726.                 else {
  2727.                     boxobject.ensureRowIsVisible(i  - previousReminderOffset);
  2728.                 }                    
  2729.             }        
  2730.         }
  2731.         
  2732.         if ( isTabSorted() ) {
  2733.             removeAllListItems( true, false );
  2734.             fillList( true, false);            
  2735.         }
  2736.         
  2737.     }
  2738. }
  2739.  
  2740.  
  2741. function setTextProperties( isToday, isImportant, isCompleted, newDateLabel, newDescLabel, newTimeLabel ) {
  2742.     
  2743.     if ( reminderFox_highlightTodayPreference && isToday && isImportant && isCompleted ) {
  2744.         newDateLabel.setAttribute("properties", "imporantCompleteTextToday");
  2745.         newDescLabel.setAttribute("properties", "imporantCompleteTextToday");
  2746.         newTimeLabel.setAttribute("properties", "imporantCompleteTextToday");
  2747.     }
  2748.     else if ( reminderFox_highlightTodayPreference && isToday && isImportant ) {
  2749.         newDateLabel.setAttribute("properties", "imporantToday");
  2750.         newDescLabel.setAttribute("properties", "imporantToday");
  2751.         newTimeLabel.setAttribute("properties", "imporantToday");
  2752.     }
  2753.     else if ( reminderFox_highlightTodayPreference && isToday && isCompleted ) {
  2754.         newDateLabel.setAttribute("properties", "todayCompleteText");    
  2755.         newDescLabel.setAttribute("properties", "todayCompleteText");
  2756.         newTimeLabel.setAttribute("properties", "todayCompleteText");    
  2757.     }
  2758.     else if ( reminderFox_highlightTodayPreference && isToday ) {
  2759.         newDateLabel.setAttribute("properties", "today");
  2760.         newDescLabel.setAttribute("properties", "today"); 
  2761.         newTimeLabel.setAttribute("properties", "today");
  2762.     }
  2763.     else if ( isImportant && isCompleted ) {
  2764.         newDateLabel.setAttribute("properties", "imporantCompleteText");        
  2765.         newDescLabel.setAttribute("properties", "imporantCompleteText");
  2766.         newTimeLabel.setAttribute("properties", "imporantCompleteText");
  2767.     }
  2768.     else if ( isImportant ) {
  2769.         newDateLabel.setAttribute("properties", "important");        
  2770.         newDescLabel.setAttribute("properties", "important");
  2771.         newTimeLabel.setAttribute("properties", "important");
  2772.     }
  2773.     else if ( isCompleted ) {
  2774.         newDateLabel.setAttribute("properties", "completeText");        
  2775.         newDescLabel.setAttribute("properties", "completeText");
  2776.         newTimeLabel.setAttribute("properties", "completeText");
  2777.     }
  2778.     else {    
  2779.         newDateLabel.removeAttribute("properties");
  2780.         newDescLabel.removeAttribute("properties");
  2781.         newTimeLabel.removeAttribute("properties");
  2782.     }        
  2783.     
  2784.     
  2785. }
  2786.  
  2787. function createListItemSorted(reminder, todaysDate) {
  2788.  
  2789. //gW View 2008-10-15
  2790.     if (rmFx_ViewThis(reminder) == 0)  {return};
  2791.  
  2792.     if ( isListFiltered( )) {             
  2793.         var rmSearchText =lastRmSearchText.toLowerCase();
  2794.         try {        //  'try'    to skip for invalid 'Item' description    
  2795.            var xx = reminder[searchItems[currentRmSearchItemValue]].toLowerCase();
  2796.             if (searchItems[currentRmSearchItemValue] == "categories") {
  2797.                 xx = reminderFox_unEscapeCommas(xx);
  2798.             }  
  2799.             if (xx.search(rmSearchText) == -1) {
  2800.                 return;
  2801.             }
  2802.         } catch (e)  { return};
  2803.     }
  2804.     
  2805.     var once = document.getElementById("occurrence");
  2806.     var treeChildren = document.getElementById("treechildren");
  2807.  
  2808.     var newItem = document.createElement("treeitem");
  2809.     var newRow = document.createElement("treerow");
  2810.     newRow.setAttribute( REMINDER_ID_REF, reminder.id );
  2811.     
  2812.     var newDateLabel = document.createElement("treecell");
  2813.     var newDescLabel = document.createElement("treecell");
  2814.     
  2815.     newItem.appendChild(newRow);  
  2816.     newRow.appendChild(newDateLabel);
  2817.     newRow.appendChild(newDescLabel);
  2818.     
  2819.      var isToday = reminderFox_compareDates( reminder.date, todaysDate) == 0 ;
  2820.      var isImportant = reminder.priority == REMINDER_PRIORITY_IMPORTANT;
  2821.      var isCompleted =  reminderFox_isCompletedForDate( reminder, reminder.date);
  2822.         
  2823.     var monthAsText = reminderFox_getMonthAsText(reminder.date.getMonth());    
  2824.     if ( useDefaultDate ) {
  2825.         newDateLabel.setAttribute("label", monthAsText + " " +  reminder.date.getDate());
  2826.     }
  2827.     else {
  2828.         newDateLabel.setAttribute("label", reminderFox_getDateVariableString( reminder, reminder.date ) );
  2829.     }    
  2830.     
  2831.     newRow.setAttribute( REMINDER_DATE_REF, reminder.date.getTime() );
  2832.  
  2833.     newDescLabel.setAttribute("label", reminder.summary);
  2834.             
  2835.     var newTimeLabel = document.createElement("treecell");
  2836.     newRow.appendChild(newTimeLabel);        
  2837.     
  2838.     var newCompletedDateLabel = document.createElement("treecell");
  2839.     newRow.appendChild(newCompletedDateLabel);                
  2840.             
  2841.     
  2842.     var newRepeatLabel = document.createElement("treecell");
  2843.     newRow.appendChild(newRepeatLabel);
  2844.     
  2845.     var newCompleteLabel = document.createElement("treecell");
  2846.     newRow.appendChild(newCompleteLabel);
  2847.     
  2848.     var newRemindUntilCompletedLabel = document.createElement("treecell");
  2849.     newRow.appendChild(newRemindUntilCompletedLabel);
  2850.     
  2851.     var newNotesLabel = document.createElement("treecell");
  2852.     newRow.appendChild(newNotesLabel);    
  2853.     
  2854.     var alarmLabel = document.createElement("treecell");
  2855.     newRow.appendChild(alarmLabel);            
  2856.     
  2857.     var catLabel = document.createElement("treecell");
  2858.     newRow.appendChild(catLabel);             
  2859.     
  2860.     var endDateLabel = document.createElement("treecell");
  2861.     newRow.appendChild(endDateLabel);        
  2862.   
  2863.     setTextProperties( isToday, isImportant, isCompleted, newDateLabel, newDescLabel, newTimeLabel );             
  2864.     
  2865.     if ( isCompleted )  {
  2866.         newCompleteLabel.setAttribute("src",REMINDER_FOX_COMPLETED_IMAGE);    
  2867.         if ( useDefaultDate ) {
  2868.             var monthAsText = reminderFox_getMonthAsText(reminder.completedDate.getMonth());        
  2869.             newCompletedDateLabel.setAttribute("label", monthAsText + " " + reminder.completedDate.getDate());
  2870.         }
  2871.         else {
  2872.             newCompletedDateLabel.setAttribute("label", reminderFox_getDateVariableString( reminder, reminder.completedDate ) );
  2873.         }             
  2874.      }
  2875.      
  2876.         
  2877.     if ( reminder.endDate != null ) {
  2878.         var myEndDate = new Date( reminder.date.getTime() + reminder.durationTime );
  2879.         if ( reminder.allDayEvent ) {
  2880.             myEndDate.setDate( myEndDate.getDate() -1 ); // all-day offset
  2881.         }
  2882.         if ( useDefaultDate ) {
  2883.             var monthAsText = reminderFox_getMonthAsText(myEndDate.getMonth());        
  2884.             endDateLabel.setAttribute("label", monthAsText + " " + myEndDate.getDate());
  2885.         }
  2886.         else {
  2887.             endDateLabel.setAttribute("label", reminderFox_getDateVariableString( reminder, myEndDate ) );
  2888.         }
  2889.     }
  2890.      
  2891.      
  2892.     setRemindUntilCompleteColumn( reminder, newRemindUntilCompletedLabel );     
  2893.      
  2894.      if ( reminder.notes != null ) {
  2895.            //newNotesLabel.setAttribute("properties", "notes");
  2896.          newNotesLabel.setAttribute("src", REMINDER_FOX_NOTES_IMAGE);            
  2897.      }     
  2898.      
  2899.       if ( reminder.alarm != null ) {
  2900.         if ( reminder.snoozeTime != null && !isCompleted) { 
  2901.             alarmLabel.setAttribute("src",REMINDER_FOX_ALARM_SNOOZE_IMAGE);        
  2902.         }
  2903.         else {
  2904.              alarmLabel.setAttribute("src",REMINDER_FOX_ALARM_IMAGE);            
  2905.         }            
  2906.      }             
  2907.               
  2908.      
  2909.      if ( reminder.messageID != null ) {
  2910.          var newMailLabel = document.createElement("treecell");
  2911.         newRow.appendChild(newMailLabel);    
  2912.          newMailLabel.setAttribute("src",REMINDER_FOX_MAIL_IMAGE);            
  2913.      } 
  2914.      
  2915.         
  2916. //gW_Categories  <<<----- 
  2917.      if ( reminder.categories != null ) {     
  2918.         catLabel.setAttribute("label",reminder.categories);    
  2919.  
  2920. //             TODO:
  2921. //             newDescLabel.removeAttribute("properties");
  2922. //             newDescLabel.setAttribute( "style", " color: blue" );
  2923.              //newDescLabel.setAttribute("properties", "important");
  2924.  
  2925.      }           
  2926. //   ---->>>
  2927.  
  2928.      
  2929.      if ( reminder.allDayEvent ) {
  2930.         newTimeLabel.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  2931.     }
  2932.     else {
  2933.         var time = reminderFox_getAddTimeString(reminder);
  2934.         if ( time == null ) {
  2935.             newTimeLabel.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  2936.         }
  2937.         else {            
  2938.             newTimeLabel.setAttribute("label", time);
  2939.         }
  2940.     }
  2941.     
  2942.     if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) {
  2943.         newRepeatLabel.setAttribute("label", REPEAT_LABEL_YEARLY);
  2944.     }
  2945.     else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) {
  2946.         newRepeatLabel.setAttribute("label", REPEAT_LABEL_YEARLY_DAY);
  2947.     }        
  2948.     else     if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
  2949.         newRepeatLabel.setAttribute("label", REPEAT_LABEL_MONTHLY);
  2950.     }
  2951.     else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {
  2952.         newRepeatLabel.setAttribute("label", REPEAT_LABEL_MONTHLY_DAY);
  2953.     }
  2954.     else    if ( reminder.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {        
  2955.         newRepeatLabel.setAttribute("label", REPEAT_LABEL_WEEKLY);
  2956.     }
  2957.     else     if ( reminder.recurrence.type  == REMINDER_RECURRENCE_DAILY ) {
  2958.         newRepeatLabel.setAttribute("label", REPEAT_LABEL_DAILY);
  2959.     }
  2960.     else {        
  2961.         newRepeatLabel.setAttribute("label", REPEAT_LABEL_NONE);
  2962.     }        
  2963.     
  2964.     treeChildren.appendChild(newItem);        
  2965. }
  2966.  
  2967. function getCurrentTodoList() {
  2968.     var todosArr =    reminderFox_getReminderTodos();
  2969.     var tabList = document.getElementById("tabList");    
  2970.     var tab =    tabList.selectedItem;
  2971.     var tabIndex =    tabList.selectedIndex;
  2972.     var index = tab.id.indexOf( ':' );
  2973.     if ( tabIndex <= 1 || index == -1 ) {
  2974.         name = REMINDER_FOX_DEFAULT_TODOS_CATEGORY;
  2975.     }
  2976.     else {
  2977.         name = tab.id.substring( index +1 , tab.id.length );
  2978.     }
  2979.     var todos = todosArr[name];
  2980.     if ( todos == null ) {
  2981.         todos = new Array();
  2982.         todosArr[name] = todos;
  2983.     }
  2984.     return todos;
  2985. }
  2986.  
  2987. function getCurrentReminderList() {
  2988.     if ( isSubscribedCalendarTabSelected() ) {
  2989.         var subscribedCalArr =    getSubscribedCalendars();
  2990.         var tabList = document.getElementById("tabList");    
  2991.         var tab =    tabList.selectedItem;
  2992.         var tabIndex =    tabList.selectedIndex;
  2993.         var index = tab.id.indexOf( ':' );        
  2994.         name = tab.id.substring( index +1 , tab.id.length );
  2995.         
  2996.         var subscribedCal = subscribedCalArr[name];
  2997.         if ( subscribedCal == null  ) { // || subscribedCal.length == 0 ) {
  2998.             // download this subscription...
  2999.             subscribedCal = new Array();
  3000.             subscribedCalArr[name] = subscribedCal;
  3001.             // start downloading in background 
  3002.             setTimeout( reminderFox_downloadSubscribedCalendar, 1, name, subscribedCal);
  3003.         }
  3004.         return subscribedCal;
  3005.     }
  3006.     else {
  3007.         var reminders = reminderFox_getReminderEvents();      
  3008.         return reminders;
  3009.     }    
  3010. }
  3011.  
  3012. function getSubscribedCalendars() {
  3013.         if ( reminderFox_subscribedCalendars == null ) {
  3014.             reminderFox_subscribedCalendars = { };
  3015.         }    
  3016.          
  3017.         return reminderFox_subscribedCalendars;
  3018.     }
  3019.     
  3020.     
  3021.     
  3022. function reminderFox_downloadSubscribedCalendar(name, subscribedCal) {
  3023.     // sync 'em up 
  3024.     var statusTxt = document.getElementById("reminderFox-network-status");
  3025.     
  3026.     
  3027.     var subscriptions = reminderFox_getSubscriptions();    
  3028.     var url = subscriptions[name];
  3029.     if ( url != null && url.length > 0 ) {
  3030.         rmFxCore.statusSet (g_reminderFoxBundle.getString("rf.options.customlist.subscribe.retrieve.title") + " " + url);
  3031.         var webcalIndex = url.indexOf( "webcal://");      // handle webcal address
  3032.         if ( webcalIndex != -1 ) {
  3033.             url = "http://" + url.substring( "webcal://".length );
  3034.         }
  3035.         reminderFox_download_Startup_headless_URL(REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS,reminderFox_downloadSubscribedCalendarCallback, url, subscribedCal, null);
  3036.     }
  3037.     
  3038. }
  3039.  
  3040. function reminderFox_downloadSubscribedCalendarCallback( statustxtString, actionID, downloadedReminders ) {
  3041.         
  3042.         if ( actionID == 1 ) {  // completed successfully (remote and local are equal, or were uploaded)
  3043.             rmFxCore.statusSet ("");
  3044.         }
  3045.         else if ( actionID == 2 ) { // reminders were downloaded,  need to refresh reminders 
  3046.             var subscribedCalArr =    getSubscribedCalendars();
  3047.             var tabList = document.getElementById("tabList");    
  3048.             var tab =    tabList.selectedItem;
  3049.             var tabIndex =    tabList.selectedIndex;
  3050.             var index = tab.id.indexOf( ':' );        
  3051.             name = tab.id.substring( index +1 , tab.id.length );
  3052.             
  3053.             var subscribedCal = subscribedCalArr[name];
  3054.             if ( subscribedCal == null ) {                
  3055.                 subscribedCal = new Array();
  3056.                 subscribedCalArr[name] = subscribedCal;
  3057.             }
  3058.             subscribedCal = downloadedReminders;
  3059.                 
  3060.             selectCalendarSync = false;
  3061.              // remove all of the calendar items and re-add them
  3062.             removeAllListItems( true, false);      
  3063.             calendarReminderArray = null;  // null out in case reminder columns are sorted
  3064.             fillList(true, false);    
  3065.             selectCalendarSync = true;   
  3066.            
  3067.            oeDatePicker.redrawYear();
  3068.            oeDatePicker.redrawDays();            
  3069.             rmFxCore.statusSet ("");
  3070.         }
  3071.         else {
  3072.             rmFxCore.statusSet (statustxtString);
  3073.         }
  3074.         
  3075. }
  3076.  
  3077.     
  3078.  
  3079. function createTodoListItem(todo, sort, todaysDate, addToArray ) {
  3080.     var tree ;
  3081.     var treeSelection
  3082.     var boxobject;
  3083.     var item;    
  3084.  
  3085.  
  3086.     if (rmFx_ViewThis(todo) == 0)  {return};
  3087.  
  3088. //gW_Search <<< ------    
  3089.         if ( isListFiltered( )) {
  3090.             var rmSearchText =lastTodoSearchText.toLowerCase();
  3091.             try {        /*  'try'    to skip for invalid 'Item' description */
  3092.                 if (todo[searchItems[currentTodoSearchItemValue]].toLowerCase().search(rmSearchText) == -1) {
  3093.                      return;
  3094.                 }                     
  3095.             } catch (e)  {return};
  3096.         }
  3097. // --->>>
  3098.  
  3099.     // if this todo is completed and the user wants to hide completed items,
  3100.     // don't add it to the list
  3101.     if (HIDE_COMPLETED_ITEMS &&
  3102.              todo.completedDate != null ) { 
  3103.         return;    
  3104.     }
  3105.  
  3106.     var treeChildren = document.getElementById("todoTreechildren");
  3107.     var newItem = document.createElement("treeitem");
  3108.     var newRow = document.createElement("treerow");
  3109.     newRow.setAttribute( REMINDER_ID_REF, todo.id );    
  3110.     var newDateLabel = document.createElement("treecell");
  3111.     var newDescLabel = document.createElement("treecell");
  3112.                       newDescLabel.setAttribute("align", "end");
  3113.     
  3114.     newItem.appendChild(newRow);
  3115.     newRow.appendChild(newDateLabel);
  3116.     newRow.appendChild(newDescLabel);
  3117.     var isImportant = false;
  3118.     
  3119.     if ( todo.date != null ) {
  3120.         var monthAsText = reminderFox_getMonthAsText(todo.date.getMonth());        
  3121.         if ( useDefaultDate ) {
  3122.             newDateLabel.setAttribute("label", monthAsText + " " + todo.date.getDate());
  3123.         }
  3124.         else {
  3125.             newDateLabel.setAttribute("label", reminderFox_getDateVariableString( todo, todo.date ) );
  3126.         }    
  3127.         newRow.setAttribute( REMINDER_DATE_REF, todo.date.getTime() );
  3128. //        var dayVal = todo.date.getDate();
  3129. //        var monthArray = calendarTodoArray[todo.date.getMonth()];
  3130. //        if ( monthArray == null ) {
  3131. //            monthArray = new Array(31);
  3132. //            calendarTodoArray[todo.date.getMonth()] = monthArray;
  3133. //        }
  3134.  
  3135. //        todo = reminderFox_processReminderDescription(reminder, todaysDate.getFullYear(), false);    
  3136.         if ( addToArray ) {
  3137.             if ( calendarTodoArray == null ) { 
  3138.                 //createCalendarTodoArray();                
  3139.                 calendarTodoArray = new Array(12);  
  3140.             }
  3141.         
  3142.             todo = reminderFox_processReminderDescription(todo, todaysDate.getFullYear(), false);    
  3143.         
  3144.             var monthArray = calendarTodoArray[todo.date.getMonth()];
  3145.             if ( monthArray == null ) {
  3146.                 monthArray = new Array(31);
  3147.                 calendarTodoArray[todo.date.getMonth()] = monthArray;
  3148.             }
  3149.                 
  3150.             var monthDay = todo.date.getDate();
  3151.             var dayReminderArray = monthArray[monthDay - 1];
  3152.             if ( dayReminderArray == null ) {
  3153.                 dayReminderArray = new Array();
  3154.                 monthArray[monthDay - 1] = dayReminderArray;
  3155.             }
  3156.             length = dayReminderArray.length;
  3157.             
  3158.             var ignoreReminder = false;            
  3159.             if (HIDE_COMPLETED_ITEMS &&
  3160.                          todo.completedDate != null ) { 
  3161.                     ignoreReminder = true;            
  3162.             }
  3163.     
  3164.             if ( !ignoreReminder ) {
  3165.                 dayReminderArray[length] = todo;
  3166.             }    
  3167.         }
  3168.             
  3169.  
  3170. //    if ( calendarTodoArray == null ) {
  3171. //        createCalendarTodoArray();
  3172. //    }
  3173.  
  3174. //    createCalendarTodoArray();
  3175.         
  3176.     }
  3177.  
  3178.     todo = reminderFox_processReminderDescription(todo,  todaysDate.getFullYear(), true );        
  3179.     newDescLabel.setAttribute("label", todo.summary);
  3180.     
  3181.     var newTimeLabel = document.createElement("treecell");
  3182.     newRow.appendChild(newTimeLabel);            
  3183.     if ( todo.date != null ) { 
  3184.         if ( todo.allDayEvent ) {
  3185.             newTimeLabel.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  3186.         }
  3187.         else {
  3188.             var time = reminderFox_getAddTimeString(todo);
  3189.             if ( time == null ) {
  3190.                 newTimeLabel.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  3191.             }
  3192.             else {            
  3193.                 newTimeLabel.setAttribute("label", time);
  3194.             }
  3195.         }
  3196.     }
  3197.     
  3198.     var newCompletedDateLabel = document.createElement("treecell");
  3199.     newRow.appendChild(newCompletedDateLabel);                
  3200.             
  3201.     
  3202.     var newCompletedLabel = document.createElement("treecell");
  3203.     newRow.appendChild(newCompletedLabel);
  3204.  
  3205.     var newTodoShowInTooltip = document.createElement("treecell");
  3206.     newRow.appendChild(newTodoShowInTooltip);
  3207.     
  3208.     // check for any options that are specified, and mark them in the columns 
  3209.     if ( todo.priority == REMINDER_PRIORITY_IMPORTANT) { 
  3210.             newDescLabel.setAttribute("properties", "important");
  3211.             isImportant = true;
  3212.      }
  3213.      
  3214.      if ( todo.completedDate != null  ) {
  3215.          newCompletedLabel.setAttribute("src",REMINDER_FOX_COMPLETED_TODO_IMAGE);            
  3216.          if ( isImportant ) {
  3217.              newDescLabel.setAttribute("properties", "imporantCompleteText");         
  3218.          }
  3219.          else {
  3220.              newDescLabel.setAttribute("properties", "completeText");         
  3221.          }
  3222.          
  3223.         if ( useDefaultDate ) {
  3224.             var monthAsText = reminderFox_getMonthAsText(todo.completedDate.getMonth());        
  3225.             newCompletedDateLabel.setAttribute("label", monthAsText + " " + todo.completedDate.getDate());
  3226.         }
  3227.         else {
  3228.             newCompletedDateLabel.setAttribute("label", reminderFox_getDateVariableString( todo, todo.completedDate ) );
  3229.         }         
  3230.      }
  3231.      
  3232.      if ( todo.showInTooltip ) {
  3233.               newTodoShowInTooltip.setAttribute("src", REMINDER_FOX_SHOW_IN_TOOLTIP_IMAGE);        
  3234.      }    
  3235.      
  3236.     var newNotesLabel = document.createElement("treecell");
  3237.     newRow.appendChild(newNotesLabel);    
  3238.       if ( todo.notes != null ) {
  3239.          newNotesLabel.setAttribute("src",REMINDER_FOX_NOTES_IMAGE);            
  3240.          //newNotesLabel.setAttribute("properties", "align='center'");
  3241.          //     newNotesLabel.setAttribute("align", "end");
  3242.          //newNotesLabel.setAttribute("properties", "notes");         
  3243.      }         
  3244.      
  3245.     var alarmLabel = document.createElement("treecell");
  3246.     newRow.appendChild(alarmLabel);             
  3247.     
  3248.      if ( todo.alarm != null ) {
  3249.         if ( todo.snoozeTime != null && todo.completedDate == null  ) { 
  3250.             alarmLabel.setAttribute("src",REMINDER_FOX_ALARM_SNOOZE_IMAGE);        
  3251.         }
  3252.         else {
  3253.              alarmLabel.setAttribute("src",REMINDER_FOX_ALARM_IMAGE);            
  3254.         }
  3255.      }           
  3256.      
  3257.      
  3258.        var categoriesLabel = document.createElement("treecell");
  3259.     newRow.appendChild(categoriesLabel);        
  3260.     if ( todo.categories != null ) {
  3261.          categoriesLabel.setAttribute("label", todo.categories);
  3262.     }
  3263.  
  3264.     var endDateLabel = document.createElement("treecell");
  3265.     newRow.appendChild(endDateLabel);        
  3266.     
  3267.     if ( todo.date != null && todo.endDate != null ) {
  3268.         var myEndDate = new Date( todo.date.getTime() + todo.durationTime );
  3269.         if ( todo.allDayEvent ) {
  3270.             myEndDate.setDate( myEndDate.getDate() -1 ); // all-day offset
  3271.         }
  3272.         if ( useDefaultDate ) {
  3273.             var monthAsText = reminderFox_getMonthAsText(myEndDate.getMonth());        
  3274.             endDateLabel.setAttribute("label", monthAsText + " " + myEndDate.getDate());
  3275.         }
  3276.         else {
  3277.             endDateLabel.setAttribute("label", reminderFox_getDateVariableString( todo, myEndDate ) );
  3278.         }
  3279.     }
  3280.  
  3281.  
  3282.      if ( todo.messageID != null ) {
  3283.          var newMailLabel = document.createElement("treecell");
  3284.         newRow.appendChild(newMailLabel);    
  3285.          newMailLabel.setAttribute("src",REMINDER_FOX_MAIL_IMAGE);            
  3286.      }     
  3287.     
  3288.     var treeitems = treeChildren.childNodes;
  3289.     if( !sort || treeitems.length == 0 ) {
  3290.         treeChildren.appendChild(newItem);
  3291.         if ( treeitems.length == 1 ) {
  3292.             var treeSelection = document.getElementById("todoTree").view.selection;    
  3293.             treeSelection.select(0);
  3294.         }
  3295.     }
  3296.     // if current todo is not important, add after important items
  3297.     else if ( !isImportant) {
  3298.         var added = false;
  3299.         for (var i=0; i < treeitems.length && !added; i++) {
  3300.             item = treeitems[i];
  3301.             var row = item.childNodes[0];
  3302.             var todoRefId = row.getAttribute(REMINDER_ID_REF);            
  3303.             var todoAtIndex = reminderFox_getTodosById( todoRefId,  getCurrentTodoList() );        
  3304.  
  3305.             var descCell = row.childNodes[0];
  3306.             var descLabel = descCell.getAttribute("label");        
  3307.              if ( !todoAtIndex.priority == REMINDER_PRIORITY_IMPORTANT ) {
  3308.                 if (  todo.showInTooltip ) {
  3309.                      treeChildren.insertBefore(newItem, item);
  3310.                     added = true;                
  3311.                     // highlight the newly added reminder in the list
  3312.                     tree = document.getElementById("todoTree");    
  3313.                     treeSelection = tree.view.selection;    
  3314.                     treeSelection.select(i);                    
  3315.     
  3316.                     boxobject = tree.boxObject;
  3317.                     boxobject.ensureRowIsVisible(i);
  3318.                 }
  3319.                 else {
  3320.                     if ( !todoAtIndex.showInTooltip  ) {
  3321.                         treeChildren.insertBefore(newItem, item);
  3322.                         added = true;
  3323.                         // highlight the newly added reminder in the list
  3324.                         tree = document.getElementById("todoTree");    
  3325.                         treeSelection = tree.view.selection;    
  3326.                         treeSelection.select(i);
  3327.                         
  3328.                         boxobject = tree.boxObject;
  3329.                         boxobject.ensureRowIsVisible(i);
  3330.                     }
  3331.                 }
  3332.             
  3333.             }
  3334.         }
  3335.     
  3336.         if ( !added ) {
  3337.                treeChildren.appendChild(newItem);
  3338.             // highlight the newly added reminder in the list      
  3339.             tree = document.getElementById("todoTree");    
  3340.             treeSelection = tree.view.selection;    
  3341.             treeSelection.select(treeitems.length - 1);            
  3342.                             
  3343.             boxobject = tree.boxObject;
  3344.             boxobject.ensureRowIsVisible(treeitems.length - 1);
  3345.        }
  3346.     }
  3347.     // new Todo is important - add to top of list
  3348.     else {                
  3349.         item = treeitems[0];
  3350.         treeChildren.insertBefore(newItem, item);
  3351.         added = true;    
  3352.         // highlight the newly added reminder in the list
  3353.         tree = document.getElementById("todoTree");    
  3354.         treeSelection = tree.view.selection;    
  3355.         treeSelection.select(0);
  3356.  
  3357.         boxobject = tree.boxObject;
  3358.         boxobject.ensureRowIsVisible(0);
  3359.     }    
  3360.           
  3361.     
  3362. }
  3363.  
  3364.  
  3365. function createTodoListItemAtIndex(todo, index) {
  3366.     var tree ;
  3367.     var treeSelection
  3368.     var boxobject;
  3369.     var item;    
  3370.  
  3371.     var treeChildren = document.getElementById("todoTreechildren");
  3372.     var newItem = document.createElement("treeitem");
  3373.     var newRow = document.createElement("treerow");
  3374.     newRow.setAttribute( REMINDER_ID_REF, todo.id );    
  3375.     var newDateLabel = document.createElement("treecell");    
  3376.     var newDescLabel = document.createElement("treecell");
  3377.  
  3378.     newItem.appendChild(newRow);
  3379.     newRow.appendChild(newDateLabel);
  3380.     newRow.appendChild(newDescLabel);
  3381.     var isImportant = false;
  3382.     
  3383.     if ( todo.date != null ) {
  3384.         var monthAsText = reminderFox_getMonthAsText(todo.date.getMonth());        
  3385.         if ( useDefaultDate ) {
  3386.             newDateLabel.setAttribute("label", monthAsText + " " + todo.date.getDate());
  3387.         }
  3388.         else {
  3389.             newDateLabel.setAttribute("label", reminderFox_getDateVariableString( todo, todo.date ) );
  3390.         }    
  3391.         newRow.setAttribute( REMINDER_DATE_REF, todo.date.getTime() );
  3392.     }    
  3393.     todo = reminderFox_processReminderDescription(todo,  new Date().getFullYear(), true );            
  3394.     newDescLabel.setAttribute("label", todo.summary);
  3395.     var newTimeLabel = document.createElement("treecell");
  3396.     newRow.appendChild(newTimeLabel);            
  3397.     if ( todo.date != null ) { 
  3398.         if ( todo.allDayEvent ) {
  3399.             newTimeLabel.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  3400.         }
  3401.         else {
  3402.             var time = reminderFox_getAddTimeString(todo);
  3403.             if ( time == null ) {
  3404.                 newTimeLabel.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  3405.             }
  3406.             else {            
  3407.                 newTimeLabel.setAttribute("label", time);
  3408.             }
  3409.         }    
  3410.     }
  3411.     
  3412.     var newCompletedDateLabel = document.createElement("treecell");
  3413.     newRow.appendChild(newCompletedDateLabel);                
  3414.             
  3415.  
  3416.     var newCompletedLabel = document.createElement("treecell");
  3417.     newRow.appendChild(newCompletedLabel);
  3418.                 
  3419.     var newTodoShowInTooltip = document.createElement("treecell");
  3420.     newRow.appendChild(newTodoShowInTooltip);
  3421.     
  3422.     // check for any options that are specified, and mark them in the columns 
  3423.     if ( todo.priority == REMINDER_PRIORITY_IMPORTANT) { 
  3424.             newDescLabel.setAttribute("properties", "important");
  3425.             isImportant = true;
  3426.      }
  3427.      
  3428.      if ( todo.completedDate != null  ) {
  3429.          newCompletedLabel.setAttribute("src",REMINDER_FOX_COMPLETED_TODO_IMAGE);    
  3430.          if ( isImportant ) {
  3431.              newDescLabel.setAttribute("properties", "imporantCompleteText");         
  3432.          }
  3433.          else {
  3434.              newDescLabel.setAttribute("properties", "completeText");         
  3435.          }    
  3436.                   
  3437.         if ( useDefaultDate ) {
  3438.             var monthAsText = reminderFox_getMonthAsText(todo.completedDate.getMonth());        
  3439.             newCompletedDateLabel.setAttribute("label", monthAsText + " " + todo.completedDate.getDate());
  3440.         }
  3441.         else {
  3442.             newCompletedDateLabel.setAttribute("label", reminderFox_getDateVariableString( todo, todo.completedDate ) );
  3443.         }              
  3444.      }     
  3445.      
  3446.      if ( todo.showInTooltip ) {    
  3447.               newTodoShowInTooltip.setAttribute("src", REMINDER_FOX_SHOW_IN_TOOLTIP_IMAGE);                 
  3448.      }    
  3449.     
  3450.     var newNotesLabel = document.createElement("treecell");
  3451.     newRow.appendChild(newNotesLabel);    
  3452.       if ( todo.notes != null ) {
  3453.          newNotesLabel.setAttribute("src",REMINDER_FOX_NOTES_IMAGE);            
  3454.          //newNotesLabel.setAttribute("properties", "align='center'");
  3455.          newNotesLabel.setAttribute("align", "end");
  3456.          //newNotesLabel.setAttribute("properties", "notes");             
  3457.      }              
  3458.     
  3459.     var alarmLabel = document.createElement("treecell");
  3460.     newRow.appendChild(alarmLabel);             
  3461.     
  3462.      if ( todo.alarm != null ) {
  3463.         if ( todo.snoozeTime != null && todo.completedDate == null ) { 
  3464.             alarmLabel.setAttribute("src",REMINDER_FOX_ALARM_SNOOZE_IMAGE);        
  3465.         }
  3466.         else {
  3467.              alarmLabel.setAttribute("src",REMINDER_FOX_ALARM_IMAGE);            
  3468.         }                
  3469.      }           
  3470.      
  3471.     var categoriesLabel = document.createElement("treecell");
  3472.     newRow.appendChild(categoriesLabel);            
  3473.     if ( todo.categories != null ) {
  3474.          categoriesLabel.setAttribute("label", todo.categories);
  3475.     }          
  3476.     
  3477.     var endDateLabel = document.createElement("treecell");
  3478.     newRow.appendChild(endDateLabel);        
  3479.     if ( todo.date != null && todo.endDate != null ) {
  3480.         var myEndDate = new Date( todo.date.getTime() + todo.durationTime );
  3481.         if ( todo.allDayEvent ) {
  3482.             myEndDate.setDate( myEndDate.getDate() -1 ); // all-day offset
  3483.         }
  3484.         if ( useDefaultDate ) {
  3485.             var monthAsText = reminderFox_getMonthAsText(myEndDate.getMonth());        
  3486.             endDateLabel.setAttribute("label", monthAsText + " " + myEndDate.getDate());
  3487.         }
  3488.         else {
  3489.             endDateLabel.setAttribute("label", reminderFox_getDateVariableString( todo, myEndDate ) );
  3490.         }
  3491.     }
  3492.      
  3493.      if ( todo.messageID != null ) {
  3494.          var newMailLabel = document.createElement("treecell");
  3495.         newRow.appendChild(newMailLabel);    
  3496.          newMailLabel.setAttribute("src",REMINDER_FOX_MAIL_IMAGE);            
  3497.      }          
  3498.     
  3499.     var treeitems = treeChildren.childNodes;    
  3500.     // insert at end if last item
  3501.     if ( index >= treeitems.length ) {
  3502.         treeChildren.appendChild(newItem);
  3503.         // highlight the newly added reminder in the list      
  3504.         tree = document.getElementById("todoTree");    
  3505.         treeSelection = tree.view.selection;    
  3506.         treeSelection.select(treeitems.length -1 );            
  3507.                         
  3508.         boxobject = tree.boxObject;
  3509.         boxobject.ensureRowIsVisible(treeitems.length -1 );    
  3510.     
  3511.     }
  3512.     else {
  3513.         // otherwise insert before current item at index
  3514.         item = treeitems[index ];
  3515.         treeChildren.insertBefore(newItem, item);
  3516.         
  3517.         tree = document.getElementById("todoTree");    
  3518.         treeSelection = tree.view.selection;    
  3519.         treeSelection.select(index);                    
  3520.     
  3521.         boxobject = tree.boxObject;
  3522.         boxobject.ensureRowIsVisible(index);    
  3523.     }
  3524. }
  3525.  
  3526.  
  3527. /**
  3528.   * select (highlight) today's reminder or the next upcoming reminder
  3529.   */
  3530. function highlightClosestUpcomingReminder(currentDate) {
  3531.     var currentMonth = currentDate.getMonth();
  3532.     var currentDay = currentDate.getDate();
  3533.     var treeChildren = document.getElementById("treechildren");
  3534.     var treeitems = treeChildren.childNodes;
  3535.     
  3536.     //gwTEST +++2do  get selected events into visable part of bug
  3537.     //    https://www.mozdev.org/bugs/show_bug.cgi?id=21565
  3538.     var tree = document.getElementById("reminderTree");           
  3539.     var boxobject = tree.boxObject;
  3540.     boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  3541.     boxobject.scrollToRow(0);
  3542.  
  3543.     for (var i=0; i < treeitems.length; i++) {
  3544.         var item = treeitems[i];
  3545.         var row = item.childNodes[0];
  3546.         
  3547.         var reminderDateTime = row.getAttribute(REMINDER_DATE_REF);    
  3548.         var reminderDate = new Date(parseInt(reminderDateTime));
  3549.         if ( reminderDate.getMonth() > currentMonth || (reminderDate.getMonth() == currentMonth && reminderDate.getDate() >= currentDay ) ) {
  3550.             var treeSelection = document.getElementById("reminderTree").view.selection;
  3551.             if ( treeSelection != null ) {
  3552.                 try { 
  3553.                     treeSelection.select(i);
  3554.                 }
  3555.                 catch ( e ) {
  3556.                     // when changing calendar years, selecting an event and syncing to the calendar seemed screwed up
  3557.                 }
  3558.             }
  3559.             
  3560.             // make sure that newly selected row is shown in scroll pane
  3561.             var value = document.getElementById("treeparent").value;
  3562.               var tree = document.getElementById("reminderTree");            
  3563.             var boxobject = tree.boxObject;
  3564.             boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  3565.             
  3566.             // make sure it shows up at the top if possible
  3567.             var first = boxobject.getFirstVisibleRow();
  3568.             var last = boxobject.getLastVisibleRow();
  3569.             if ( i < first || i > last ) {                
  3570.                 boxobject.scrollToRow(treeitems.length - 9);
  3571.             }
  3572.             
  3573.             var previousReminderOffset = 3;
  3574.             if ( i < previousReminderOffset ) { 
  3575.                 boxobject.ensureRowIsVisible(i);
  3576.             }
  3577.             else {
  3578.                 boxobject.ensureRowIsVisible(i  - previousReminderOffset);
  3579.             }
  3580.             break;
  3581.         }
  3582.     }
  3583. }
  3584.  
  3585. /**
  3586.   * select (highlight) today's reminder or the next upcoming reminder
  3587.   */
  3588. function highlightReminderForDate(currentMonth, currentDay) { 
  3589.     var highlighted = false;
  3590.     var treeChildren = document.getElementById("treechildren");
  3591.     var treeitems = treeChildren.childNodes;
  3592.     for (var i=0; i < treeitems.length; i++) {
  3593.         var item = treeitems[i];
  3594.         var row = item.childNodes[0];
  3595.         
  3596.         var reminderDateTime = row.getAttribute(REMINDER_DATE_REF);    
  3597.         var reminderDate = new Date(parseInt(reminderDateTime));        
  3598.  
  3599.         if ( reminderDate.getMonth() == currentMonth && reminderDate.getDate() == currentDay ) {
  3600.             highlighted = true;
  3601.             var treeSelection = document.getElementById("reminderTree").view.selection        
  3602.             if ( treeSelection != null ) {
  3603.                 treeSelection.select(i);
  3604.             }
  3605.  
  3606.             // make sure that newly selected row is shown in scroll pane
  3607.             var value = document.getElementById("treeparent").value;
  3608.               var tree = document.getElementById("reminderTree");            
  3609.             var boxobject = tree.boxObject;
  3610.             boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  3611.             
  3612.             // make sure it shows up at the top if possible
  3613.             var first = boxobject.getFirstVisibleRow();
  3614.             var last = boxobject.getLastVisibleRow();
  3615.             
  3616.             if ( i <= first || i >= last ) {                
  3617.                 boxobject.scrollToRow(treeitems.length - 9);
  3618.             }
  3619.             
  3620.             var previousReminderOffset = 3;
  3621.             if ( i < previousReminderOffset ) { 
  3622.                 boxobject.ensureRowIsVisible(i);
  3623.             }
  3624.             else {
  3625.                 boxobject.ensureRowIsVisible(i  - previousReminderOffset);
  3626.             }
  3627.             break;
  3628.         }
  3629.     }
  3630.     
  3631.     if ( !highlighted ) {
  3632.         selectNewReminderText();
  3633.     }
  3634. }
  3635.  
  3636. function highlightTodo() {
  3637.     var tree = document.getElementById("todoTree");            
  3638.     var treeSelection = tree.view.selection;    
  3639.     treeSelection.select(0);    
  3640.     treeSelection.clearSelection();
  3641.  
  3642.     try {            
  3643.         var boxobject = tree.boxObject;
  3644.         boxobject.ensureRowIsVisible(0);
  3645.     } catch (ex) {}    
  3646. }
  3647.  
  3648.  
  3649. function removeListItemsForReminder(reminder) {
  3650.     var treeChildren = document.getElementById("treechildren");
  3651.     var treeitems = treeChildren.childNodes;
  3652.     for (var i=treeitems.length - 1; i >= 0; i--) {
  3653.         var item = treeitems[i];
  3654.         var row = item.childNodes[0];
  3655.         var reminderRefId = row.getAttribute(REMINDER_ID_REF);    
  3656.         if ( reminderRefId == reminder.id ) {            
  3657.             treeChildren.removeChild(item);
  3658.         }
  3659.     }
  3660. }
  3661.  
  3662. function removeTodoListItem(todo) {
  3663.     var treeChildren = document.getElementById("todoTreechildren");
  3664.     var treeitems = treeChildren.childNodes;
  3665.     for (var i=0; i < treeitems.length; i++) {
  3666.         var item = treeitems[i];
  3667.         var row = item.childNodes[0];
  3668.         var todoRefId = row.getAttribute(REMINDER_ID_REF);        
  3669.         if ( todoRefId == todo.id ) {            
  3670.             treeChildren.removeChild(item);
  3671.             
  3672.             // gW 2008-12-14
  3673.             // need to clear Mail label if a message is attached to this reminder
  3674.             if ( todo.messageID != null ) {        
  3675.                 if ( window.arguments != null ) {                
  3676.                     var clearMailLabelCallback = window.arguments[1].clearMailLabelCallback;
  3677.                     if ( clearMailLabelCallback != null ) {                
  3678.                         clearMailLabelCallback(  todo.messageID );
  3679.                     }
  3680.                 }
  3681.             }    
  3682.             
  3683.             break;
  3684.         }
  3685.     }    
  3686. }
  3687.  
  3688.  
  3689. // saves and closes the 'edit reminders' dialog
  3690. function revert() {
  3691.     // there were changes.  Prompt user to revert/cancel
  3692.     // get a reference to the prompt service component.
  3693.     var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  3694.                         .getService(Components.interfaces.nsIPromptService);
  3695.  
  3696.     var flags=promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
  3697.        promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1;     
  3698.     var msg =  g_reminderFoxBundle.getString("rf.add.revert.description");
  3699.     var buttonPressed = promptService.confirmEx(window,g_reminderFoxBundle.getString("rf.add.revert.title"),
  3700.       msg,
  3701.       flags, g_reminderFoxBundle.getString("rf.add.revert.button.revert.title"), g_reminderFoxBundle.getString("rf.button.cancel"), null, null, {});          
  3702.       
  3703.     // revert pressed
  3704.     if ( buttonPressed == 0 ) {        
  3705.         revertActions();
  3706.     }    
  3707. }
  3708.  
  3709. function removeAllListItems(removeReminders, removeTodos) {
  3710.     if ( removeReminders ) {
  3711.         var reminderTree = document.getElementById("reminderTree");
  3712.         var treeChildren = document.getElementById("treechildren");
  3713.         reminderTree.removeChild(treeChildren);
  3714.         
  3715.         var newchildren = document.createElement("treechildren");
  3716.         newchildren.setAttribute("id", "treechildren");
  3717.         newchildren.setAttribute("ondblclick", "if (event.button == 0) editReminder()");
  3718.         newchildren.setAttribute("onclick", "reminderFox_toggleReminderColumns(event);");        
  3719.         
  3720.         newchildren.setAttribute("tooltip", "reminderTree-tooltip");
  3721.         reminderTree.appendChild(newchildren);
  3722.     }
  3723.  
  3724.     if ( removeTodos ) {
  3725.         var todoTreeChildren = document.getElementById("todoTreechildren");
  3726.          while (todoTreeChildren.hasChildNodes()) {    
  3727.              todoTreeChildren.removeChild(todoTreeChildren.firstChild);
  3728.            }        
  3729.      }    
  3730. }
  3731.  
  3732.  
  3733. // saves and closes the 'edit reminders' dialog
  3734. function saveSettings(isCloseDemanded) {
  3735.     var currentDate = new Date();
  3736.     var day = currentDate.getDate();
  3737.     var windowEnumerator = reminderFox_getWindowEnumerator();
  3738.     var currentWindow;
  3739.     var daysChanged = false;
  3740.  
  3741.  
  3742.     // see if the day has changed since last process
  3743.     if (windowEnumerator.hasMoreElements()) {
  3744.         currentWindow = windowEnumerator.getNext();        
  3745.         if ( currentWindow.reminderFox_lastDay != day ) {
  3746.             daysChanged = true;
  3747.         }
  3748.     }
  3749.     
  3750.     // write out column sort info
  3751.     var listSortStr = "";
  3752.     for ( var n in listSortMap ) {
  3753.         var sortInfo = listSortMap[n];
  3754.         if ( sortInfo != null ) {
  3755.             if ( listSortStr != "" ) {
  3756.                 listSortStr = listSortStr + ",";
  3757.             }
  3758.             listSortStr = listSortStr + n + "," + sortInfo.sortColumn + "," + sortInfo.sortDirection;;
  3759.         }
  3760.     }
  3761.     reminderFox_setUnicodePref( REMINDER_FOX_SORT_COLUMNS_PREF, listSortStr);        
  3762.  
  3763.     // if any events were modified or the day has changed, we want to update the tooltip and status text
  3764.     if ( g_modified || daysChanged ) {  
  3765.         reminderFox_writeOutRemindersAndTodos(false);
  3766.         
  3767.         reminderFox_processRecentReminders(true);
  3768.         try {
  3769.             // update all of the browsers
  3770.             windowEnumerator =  reminderFox_getWindowEnumerator();
  3771.             while (windowEnumerator.hasMoreElements()) {
  3772.                 var currentWindow = windowEnumerator.getNext();        
  3773.                 currentWindow.reminderFoxEvents = reminderFoxEvents;
  3774.                 currentWindow.reminderFoxTodosArray  = reminderFoxTodosArray; 
  3775.  
  3776.                 currentWindow.reminderFox_updateRemindersInWindow();            
  3777.                 currentWindow.reminderFox_clearRemindersAndTodos();
  3778.             }            
  3779.             // this callback syncs the written changes to remote and does it in the background on the calling 
  3780.             // window (otherwise we have to keep this window open until the network function callback returns)
  3781.             var syncCallback = null;
  3782.             if ( window.arguments != null ) {
  3783.                 syncCallback = window.arguments[1].callback;
  3784.             }
  3785.             if ( syncCallback != null ) {                
  3786.                 var networkSync = REMINDER_FOX_NETWORK_SYNCHRONIZE_DEFAULT;        
  3787.                 try {
  3788.                     networkSync = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_NETWORK_SYNCHRONIZE);
  3789.                 } catch(e) {
  3790.                 }    
  3791.                 if ( networkSync ) {                
  3792.                     syncCallback();            
  3793.                 }
  3794.             }    
  3795.         }
  3796.         catch(e) {
  3797.         }
  3798.     }
  3799.     else {
  3800.          reminderFox_ensureRemindersSynchronized();         
  3801.         
  3802.         // call reminderFox_intializeReminderFox to check in case the timers have stopped; this will restart 
  3803.         // it and process any reminders if necessary (such as alarms, etc)
  3804.         var processRemindersCallback = null;
  3805.         if ( window.arguments != null ) {
  3806.             processRemindersCallback = window.arguments[1].processRemindersCallback;
  3807.         }
  3808.         if ( processRemindersCallback != null ) {    
  3809.             processRemindersCallback(true);        
  3810.         }    
  3811.     }
  3812.  
  3813.     // clear reminders from memory
  3814.     reminderFox_clearRemindersAndTodos();
  3815.     g_modified = false;
  3816. }
  3817.  
  3818. function addReminderOrTodo() {
  3819.     if ( isReminderTabSelected() ) {
  3820.         addReminder(); 
  3821.     }
  3822.     else {
  3823.         addTodo();
  3824.     }
  3825. }
  3826.  
  3827. function dblClickDay(newDayItemNumber) {
  3828.    var dayNumberItem = document.getElementById( "oe-date-picker-month-day-text-" + newDayItemNumber );
  3829.    var dayNumber = dayNumberItem.getAttribute( "value" );
  3830.    
  3831.    // they may have clicked an unfilled day, if so ignore it and leave the picker up   
  3832.    if( dayNumber != "" )  {
  3833.            if ( isReminderTabSelected() ) {
  3834.             addReminder(); 
  3835.         }
  3836.         else {
  3837.             var newDate = oeDatePicker.gSelectedDate;
  3838.             if ( newDate == null ) {
  3839.                 newDate = new Date();
  3840.             }    
  3841.             addTodo(newDate);
  3842.         }
  3843.    }
  3844. }
  3845.  
  3846. // Adds the new reminder from the edit reminder dialog
  3847. function addReminder( useTodaysDate, newReminderToBeAdded) {
  3848.     var newDate = oeDatePicker.gSelectedDate;
  3849.     var todaysDate = new Date();
  3850.     if ( newDate == null ) {
  3851.         newDate = new Date();
  3852.     }    
  3853.     
  3854.     var originalYear = newDate.getFullYear();
  3855.     
  3856.     if ( useTodaysDate ) {
  3857.         // use today's date (but the selected year...)
  3858.         newDate = new Date( originalYear, todaysDate.getMonth(), todaysDate.getDate());
  3859.     }
  3860.     
  3861.     
  3862.     var copyingReminder = false;
  3863.     if ( newReminderToBeAdded == null ) {
  3864.         var reminderId =reminderFox_generateUniqueReminderId( newDate );
  3865.         newReminderToBeAdded = new ReminderFoxEvent( reminderId, newDate, "" );
  3866.     }
  3867.     else {
  3868.         copyingReminder = true;
  3869.     }
  3870.     
  3871.     var newOptions = { reminder: newReminderToBeAdded, editing:  copyingReminder,  copying: copyingReminder, addReminder: false, readonly: isSubscribedCalendarTabSelected() };
  3872.     window.openDialog("chrome://reminderfox/content/editing/reminderOptionsDialog.xul",
  3873.             "reminderOptionsDialog", "chrome,resizable,modal", newOptions );
  3874.  
  3875.     if ( newOptions.addReminder ) {
  3876.         var currentDate = new Date();
  3877.         if ( newReminderToBeAdded.alarm != null ) {
  3878.             newReminderToBeAdded.alarmLastAcknowledge = currentDate.getTime();
  3879.         }
  3880.         newReminderToBeAdded.lastModified = reminderFox_getDateAsString(currentDate );
  3881.  
  3882.         // if adding a new reminder in a different year, first set the list/calendar to the new year 
  3883.         // before adding the reminder
  3884.         if ( originalYear != newReminderToBeAdded.date.getFullYear() ) {
  3885.                oeDatePicker.gSelectedDate = newReminderToBeAdded.date;
  3886.             repopulateListForYear( originalYear, newReminderToBeAdded.date.getFullYear() );
  3887.         }
  3888.     
  3889.         // add reminder in sorted order...
  3890.         var reminders = reminderFox_getReminderEvents();    
  3891.         var sortedIndex = reminderFox_getSortedIndexOfNewReminder( reminders, newReminderToBeAdded, false );
  3892.         reminderFox_insertIntoArray( reminders, newReminderToBeAdded, sortedIndex );
  3893.         
  3894.         createListItem(newReminderToBeAdded);
  3895.         
  3896.         sortReminderIfNeccessary( newReminderToBeAdded.id);
  3897.         
  3898.         oeDatePicker.onpopupshowing(newReminderToBeAdded.date);
  3899.         modifiedReminders();
  3900.     }
  3901. }
  3902.  
  3903. function modifiedReminders() {
  3904.     g_modified = true;
  3905.  
  3906.     var revertButton= document.getElementById("revertbutton");
  3907.     // revertButton.setAttribute( "disabled", false );
  3908.     revertButton.removeAttribute("disabled");
  3909.     var revertButtonTodos= document.getElementById("revertbuttonTodos");
  3910.     // revertButtonTodos.setAttribute( "disabled", false );
  3911.     revertButtonTodos.removeAttribute("disabled");
  3912. }
  3913.  
  3914. function addTodo(selectedDate, newTodo) {
  3915.     var tabList = document.getElementById("tabList");    
  3916.     var tabIndex =    tabList.selectedIndex;
  3917.  
  3918.     var copyingTodo = false;
  3919.     if ( newTodo == null ) {
  3920.         var todoId =reminderFox_generateUniqueTodoId(selectedDate);
  3921.         newTodo = new ReminderFoxTodo(todoId, "" );
  3922.         newTodo.date = selectedDate;
  3923.         if ( tabIndex <= 1 ) {
  3924.             newTodo.showInTooltip = true;
  3925.         }
  3926.         else {
  3927.             newTodo.showInTooltip = false;   // for custom lists, default to false for show in tooltip
  3928.         }
  3929.     }
  3930.     else {
  3931.         copyingTodo = true;
  3932.     }
  3933.     
  3934.  
  3935.  
  3936.     var newOptions = { todo: newTodo, editing:  copyingTodo, copying:  copyingTodo,  addTodo: false };
  3937.     window.openDialog("chrome://reminderfox/content/editing/todoOptionsDialog.xul",
  3938.             "todoOptionsDialog", "chrome,resizable,modal", newOptions );
  3939.  
  3940.     if ( newOptions.addTodo ) {
  3941.         if ( newTodo.alarm != null ) {
  3942.             var currentDate = new Date();
  3943.             newTodo.alarmLastAcknowledge = currentDate.getTime();
  3944.         }
  3945.         // add todo in sorted order...
  3946.         var todos = getCurrentTodoList();
  3947.         var sortedIndex = reminderFox_getSortedIndexOfNewTodo(todos,  newTodo );
  3948.         reminderFox_insertIntoArray( todos, newTodo, sortedIndex );
  3949.         createTodoListItem(newTodo, true, new Date(), true);
  3950.         
  3951.         sortTodoIfNeccessary( newTodo.id);
  3952.         if ( newTodo.date != null ) {
  3953.             oeDatePicker.onpopupshowing(newTodo.date);
  3954.         }
  3955.         modifiedReminders();
  3956.         
  3957.         var desc = document.getElementById("addTodoButton");
  3958.         desc.focus();      
  3959.     }
  3960.     
  3961. }
  3962.  
  3963.  
  3964.  
  3965.  
  3966.  
  3967. function editTodo() {
  3968.     var currentTodo = getTodoForSelectedItem( );
  3969.     if ( currentTodo != null ) {
  3970.         var newOptions = { todo: currentTodo, editing:  true,  addTodo: false, showMail: false };
  3971.         window.openDialog("chrome://reminderfox/content/editing/todoOptionsDialog.xul",
  3972.                 "todoOptionsDialog", "chrome,resizable,modal", newOptions );
  3973.     
  3974.         if ( newOptions.showMail ) {             
  3975.             reminderFox_displayMailbyMsgID(currentTodo);    
  3976.             editTodo();
  3977.             return;
  3978.         }
  3979.     
  3980.         if ( newOptions.addTodo ) {             
  3981.              currentTodo = reminderFox_processReminderDescription(currentTodo,  new Date().getFullYear(), true );    
  3982.             var modified = updateTodoInList( currentTodo );
  3983.             
  3984.             sortTodoIfNeccessary( currentTodo.id);
  3985.             
  3986.             modifiedReminders();
  3987.             var newDate = new Date();
  3988.             if ( currentTodo.alarm != null ) {
  3989.                 currentTodo.alarmLastAcknowledge = newDate.getTime();
  3990.             }        
  3991.             refreshCalendar(true, false);            
  3992.         }
  3993.     }
  3994. }
  3995.  
  3996. function getInstanceDateOfLastSelected( currentReminder ) {
  3997.     var reminderID = currentReminder.id;
  3998.     var treeChildren = document.getElementById("treechildren");
  3999.     var selectedIDsHash = {};
  4000.     
  4001.     var start = new Object();
  4002.     var end = new Object();
  4003.     var numRanges =  document.getElementById("reminderTree").view.selection.getRangeCount();
  4004.     for (var t = numRanges - 1; t >=0;  t-- ) {
  4005.       document.getElementById("reminderTree").view.selection.getRangeAt(t,start,end);
  4006.       for (var v = end.value; v >= start.value; v--){
  4007.             var selectedTreeItem = treeChildren.childNodes[v];
  4008.             var reminderRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  4009.             if ( reminderRefId == currentReminder.id ) { 
  4010.                 var year = oeDatePicker.gSelectedDate.getFullYear();
  4011.                 if ( year == null ) {
  4012.                     year = new Date().getFullYear();
  4013.                 }        
  4014.                 
  4015.                 var reminderDateTime = selectedTreeItem.childNodes[0].getAttribute(REMINDER_DATE_REF);    
  4016.                 var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  4017.                 
  4018.                 return reminderInstanceDate;
  4019.             }
  4020.           }
  4021.     }
  4022.     return null;    
  4023. }
  4024.  
  4025.  
  4026.  
  4027. function removeReminder( currentReminder, promptForRecurringDelete, deleteDate, dateLabel ) {    
  4028.     if ( promptForRecurringDelete != null && promptForRecurringDelete == true) {        
  4029.         var messageID = currentReminder.messageID;
  4030.         
  4031.         if ( currentReminder.recurrence.type == REMINDER_RECURRENCE_MONTHLY_DATE ||
  4032.               currentReminder.recurrence.type == REMINDER_RECURRENCE_MONTHLY_DAY ||
  4033.               currentReminder.recurrence.type == REMINDER_RECURRENCE_WEEKLY ||
  4034.               currentReminder.recurrence.type == REMINDER_RECURRENCE_DAILY ) {
  4035.             
  4036.             // prompt user... 
  4037.             var deleteRecurrenceOnly = true;
  4038.             
  4039.             if ( deleteDate == null ) {
  4040.                 deleteDate = getInstanceDateOfLastSelected( currentReminder ); 
  4041.             }
  4042.             if ( dateLabel == null ) {
  4043.                 dateLabel = reminderFox_getDateVariableString( currentReminder, deleteDate );
  4044.             }
  4045.                                     
  4046.             var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  4047.                         .getService(Components.interfaces.nsIPromptService);
  4048.             var deleteDescription =  g_reminderFoxBundle.getString("rf.add.deleteReminderInstance.description") + "\n";
  4049.             deleteDescription += dateLabel + ": " + currentReminder.summary + "\n";
  4050.             var flags=promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
  4051.                    promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1 + 
  4052.                    promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
  4053.             var msg = deleteDescription; 
  4054.             var buttonPressed = promptService.confirmEx(window, g_reminderFoxBundle.getString("rf.add.deleteReminder.title"),  
  4055.               msg,
  4056.               flags,
  4057.               g_reminderFoxBundle.getString("rf.add.deleteReminderInstance.all.button"), 
  4058.               g_reminderFoxBundle.getString("rf.button.cancel"), 
  4059.               g_reminderFoxBundle.getString("rf.add.deleteReminderInstance.currentInstance.button"), 
  4060.               null, {});                        
  4061.         
  4062.             // cancel pressed
  4063.             if (  buttonPressed == 1 ) {
  4064.                 return ;
  4065.             }            
  4066.             
  4067.             // curent instances pressed
  4068.             if ( buttonPressed == 2 ) {    
  4069.                 if ( deleteDate != null ) {
  4070.                     deleteDate.setDate( deleteDate.getDate() + 1 );
  4071.                     var instanceReminder = reminderFox_getFirstReminderOccurrenceAfterStartDate( currentReminder, deleteDate );
  4072.                     var newReminderDate = instanceReminder.date;
  4073.                     var newReminder = reminderFox_cloneReminderFoxEvent(currentReminder);
  4074.                     newReminder.date = newReminderDate;                    
  4075.                     // if the date has changed, treat as a new reminder.  This is because 
  4076.                     // We want to re-add in the proper sorted order into the list of reminders
  4077.                     
  4078.                     removeListItemsForReminder(currentReminder); 
  4079.                     // remove from model list
  4080.                     var reminders = reminderFox_getReminderEvents();    
  4081.                     for( var i = 0; i < reminders.length; i++) {
  4082.                         if ( reminders[i].id == currentReminder.id ) {
  4083.                             reminderFox_removeElement(reminders, i);
  4084.                             break;
  4085.                         }
  4086.                     }
  4087.                     
  4088.                     // add reminder in sorted order...
  4089.                     reminders = reminderFox_getReminderEvents();                    
  4090.                     if ( newReminder.remindUntilCompleted != REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE ) {
  4091.                          newReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED;
  4092.                      }                
  4093.                     var sortedIndex = reminderFox_getSortedIndexOfNewReminder( reminders, newReminder, false );
  4094.                     reminderFox_insertIntoArray( reminders, newReminder, sortedIndex );
  4095.                     createListItem(newReminder);                
  4096.                     return;                    
  4097.                 }
  4098.              }
  4099.              else {                              
  4100.                  // delete all instances pressed  - do nothing here; we'll delete as normal
  4101.              }                                                 
  4102.         }
  4103.             
  4104.         // need to clear Mail label (if remove was called from the user)
  4105.         if ( messageID != null ) {        
  4106.             if ( window.arguments != null ) {
  4107.                 var clearMailLabelCallback = window.arguments[1].clearMailLabelCallback;
  4108.                 if ( clearMailLabelCallback != null ) {                
  4109.                     clearMailLabelCallback( messageID );
  4110.                 }
  4111.             }
  4112.         }    
  4113.     }
  4114.     
  4115.     
  4116.     // remove from UI list
  4117.     removeListItemsForReminder(currentReminder);
  4118.     
  4119.     // remove from model list
  4120.     var reminders = reminderFox_getReminderEvents();    
  4121.     for( var i = 0; i < reminders.length; i++) {
  4122.         if ( reminders[i].id == currentReminder.id ) {
  4123.             reminderFox_removeElement(reminders, i);
  4124.             break;
  4125.         }
  4126.     }
  4127. }
  4128.  
  4129.  
  4130. function removeTodo(currentTodo) {
  4131.     if ( currentTodo != null ) {
  4132.         // remove from UI list
  4133.         removeTodoListItem(currentTodo);
  4134.         
  4135.         // remove from model list
  4136.         var todos = getCurrentTodoList();
  4137.         for( var i = 0; i < todos.length; i++) {
  4138.             if ( todos[i].id == currentTodo.id ) {
  4139.                 reminderFox_removeElement(todos, i);
  4140.                 break;
  4141.             }
  4142.         }
  4143.     }
  4144.  
  4145. }
  4146.  
  4147. function activateCalendarContext(event, newDayItemNumber) {
  4148.     if ( !isReminderTabSelected() ) {
  4149.         return; 
  4150.     }
  4151.     
  4152.    var dayNumberItem = document.getElementById( "oe-date-picker-month-day-text-" + newDayItemNumber );
  4153.    var dayNumber = dayNumberItem.getAttribute( "value" );
  4154.    
  4155.    // they may have clicked an unfilled day, if so ignore it and leave the picker up   
  4156.    if( dayNumber != "" )  {
  4157.         var tree = document.getElementById("reminderTree");
  4158.         var treeContextMenu = document.getElementById("treechildren-calendar-contextmenu");
  4159.     
  4160.         var noExistingReminder = false;
  4161.     
  4162.         // modify context menu depending on Important reminder status
  4163.         var selectedTreeItemIndex = document.getElementById("reminderTree").currentIndex;
  4164.         if ( selectedTreeItemIndex == -1 ) {
  4165.             noExistingReminder = true;
  4166.         }
  4167.         var currentReminder = getReminderForSelectedItem( );
  4168.         if ( currentReminder == null ) {
  4169.             noExistingReminder = true;
  4170.         }
  4171.         else if ( currentReminder.completedDate != null ) {
  4172.             var calendarDate = new Date(oeDatePicker.gSelectedDate.getFullYear(),oeDatePicker.gSelectedDate.getMonth(), dayNumber );            
  4173.             if ( reminderFox_compareDates(calendarDate, currentReminder.completedDate ) != 1 ) {            
  4174.                 noExistingReminder = true;
  4175.             }            
  4176.         }
  4177.         
  4178.         // check that it's pointing to the current date; otherwise it means there is no current reminder for this date
  4179.         if ( !noExistingReminder ) {
  4180.             // check the date from the tree list, as the actual reminder could have an earlier date (if it's
  4181.             // set for RemindUntilComplete, for example)
  4182.             var treeChildren = document.getElementById("treechildren");
  4183.             var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  4184.             var reminderDateTime = selectedTreeItem.childNodes[0].getAttribute(REMINDER_DATE_REF);    
  4185.             var reminderInstanceDate = new Date(parseInt(reminderDateTime));            
  4186.             var day = reminderInstanceDate.getDate();
  4187.             
  4188.             if ( day != dayNumber ) {
  4189.                 noExistingReminder = true;
  4190.             }
  4191.         }
  4192.         
  4193.         var contextMenuImportant = document.getElementById("treechildren-calendar-contextmenu-important");    
  4194.         var contextMenuRemindComplete = document.getElementById("treechildren-calendar-contextmenu-remindUntilComplete");            
  4195.         var contextMenuComplete = document.getElementById("treechildren-calendar-contextmenu-markAsComplete");    
  4196.         var contextEdit = document.getElementById("treechildren-calendar-contextmenu-edit");            
  4197.         var contextDelete= document.getElementById("treechildren-calendar-contextmenu-delete");            
  4198.         //var contextMoveToTodos = document.getElementById("treechildren-calendar-contextmenu-moveToTodos");        
  4199.         if ( noExistingReminder ) {
  4200.             contextEdit.setAttribute( "disabled", true );
  4201.             contextDelete.setAttribute( "disabled", true );            
  4202.             //contextMoveToTodos.setAttribute( "disabled", true );                        
  4203.             contextMenuImportant.setAttribute( "disabled", true );
  4204.             contextMenuRemindComplete.setAttribute( "disabled", true );
  4205.             contextMenuComplete.setAttribute( "disabled", true );            
  4206.  
  4207.             contextMenuImportant.setAttribute("checked", "false");    
  4208.             contextMenuRemindComplete.setAttribute("checked", "false");     
  4209.             contextMenuComplete.setAttribute("checked", "false");                    
  4210.         }        
  4211.         else {
  4212.             contextEdit.removeAttribute( "disabled" );
  4213.             contextDelete.removeAttribute( "disabled" );
  4214.             //contextMoveToTodos.removeAttribute( "disabled" );
  4215.             contextMenuImportant.removeAttribute( "disabled" );
  4216.             contextMenuRemindComplete.removeAttribute( "disabled" );
  4217.             contextMenuComplete.removeAttribute( "disabled" );
  4218.                     
  4219.             if ( currentReminder.priority != REMINDER_PRIORITY_IMPORTANT ) {
  4220.                 contextMenuImportant.setAttribute("checked", "false");    
  4221.             }
  4222.             else {
  4223.                 contextMenuImportant.setAttribute("checked", "true");    
  4224.             }
  4225.             
  4226.             if ( currentReminder.remindUntilCompleted != REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE) {
  4227.                 contextMenuRemindComplete.setAttribute("checked", "true");     
  4228.             }
  4229.             else {
  4230.                 contextMenuRemindComplete.setAttribute("checked", "false");     
  4231.             }
  4232.             
  4233.             
  4234.             if ( currentReminder.completedDate == null ) {
  4235.                     contextMenuComplete.setAttribute("checked", "false");    
  4236.             }
  4237.             else {
  4238.                 var treeChildren = document.getElementById("treechildren");
  4239.                 var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  4240.                 var reminderDateTime = selectedTreeItem.childNodes[0].getAttribute(REMINDER_DATE_REF);    
  4241.                 var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  4242.                 
  4243.                 if ( reminderFox_isCompletedForDate( currentReminder, reminderInstanceDate ) )  {
  4244.                         contextMenuComplete.setAttribute("checked", "true");    
  4245.                 }
  4246.                 else {
  4247.                     contextMenuComplete.setAttribute("checked", "false");    
  4248.                 }
  4249.             }
  4250.         }
  4251.    }
  4252. }
  4253.  
  4254. function advanceTab() {
  4255.     var tabList = document.getElementById("tabList");        
  4256.     var tabIndex =    tabList.selectedIndex;
  4257.     var tabbox = document.getElementById("tabbox");
  4258.     if ( tabIndex == tabList.childNodes.length - 1 ) {
  4259.         var newTab = tabList.childNodes[0];
  4260.         tabbox.selectedTab = newTab;        
  4261.     } 
  4262.     else {
  4263.         var newTab = tabList.childNodes[tabIndex+1];
  4264.         tabbox.selectedTab = newTab;        
  4265.     }
  4266. }
  4267.  
  4268.  
  4269. function activateContext(event) {
  4270.     var tree = document.getElementById("reminderTree");
  4271.     var contextMenu = document.getElementById("treechildren-contextmenu");    
  4272.     
  4273.     // modify context menu depending on Important reminder status
  4274.     var selectedTreeItemIndex = document.getElementById("reminderTree").currentIndex;
  4275.     var currentReminder = getReminderForSelectedItem( );
  4276.     if ( selectedTreeItemIndex == -1 || currentReminder == null  ) {
  4277.         for ( var i = 0; i < contextMenu.childNodes.length; i++ ) {
  4278.             contextMenu.childNodes[i].setAttribute( "disabled", true );
  4279.         }
  4280.         return;
  4281.     }
  4282.     else {
  4283.         // enable all child menu items
  4284.         for ( var i = 0; i < contextMenu.childNodes.length; i++ ) {
  4285.             contextMenu.childNodes[i].removeAttribute( "disabled" );
  4286.         }        
  4287.     }
  4288.     
  4289.     var multipleRemindersSelected = false;
  4290.     var selectedReminders = getAllSelectedReminders();
  4291.     if ( selectedReminders.length > 1 ) { 
  4292.         multipleRemindersSelected = true;
  4293.     }
  4294.     
  4295.     var treechildrenContextmenuEdit = document.getElementById("treechildren-contextmenu-edit");    
  4296.     if ( multipleRemindersSelected ) { 
  4297.         // if multiple reminders selected, disable Edit
  4298.         treechildrenContextmenuEdit.setAttribute( "disabled", true );
  4299.     }
  4300.     else {
  4301.         treechildrenContextmenuEdit.removeAttribute( "disabled" );
  4302.     }    
  4303.     
  4304.     // show current lists...
  4305.     var moveToList = document.getElementById("treechildren-contextmenu-moveReminderToList-popup");    
  4306.     while (moveToList.hasChildNodes()) {
  4307.          moveToList.removeChild(moveToList.firstChild);
  4308.     }
  4309.     var tabList = document.getElementById("tabList");    
  4310.     var tab =    tabList.selectedItem;
  4311.     var tabIndex =    tabList.selectedIndex;
  4312.     var subscriptions = reminderFox_getSubscriptions();
  4313.     var i = 1;
  4314.     if ( isSubscribedCalendarTabSelected() ) {
  4315.         i = 0;  // allow reminder tab
  4316.     }
  4317.     for ( ; i < tabList.childNodes.length; i++ ) {  // i =1, because we want to skip reminders
  4318.         var tablistItem = tabList.childNodes[i];    
  4319.         var tabLabel = tablistItem.getAttribute("label");
  4320.         if ( subscriptions[tabLabel] == null ) {  // ignore subscribed calendars
  4321.             var menuItem = document.createElement("menuitem");
  4322.             menuItem.setAttribute( "label", tabLabel );
  4323.             menuItem.setAttribute( "oncommand", "userMoveReminderToTodo(event.target)");
  4324.             moveToList.appendChild(menuItem);
  4325.         }
  4326.     }    
  4327.     
  4328.     var contextMenuImportant = document.getElementById("treechildren-contextmenu-important");    
  4329.     if ( currentReminder.priority != REMINDER_PRIORITY_IMPORTANT ) {
  4330.         contextMenuImportant.setAttribute("checked", "false");    
  4331.     }
  4332.     else {
  4333.         contextMenuImportant.setAttribute("checked", "true");    
  4334.     }
  4335.     
  4336.     var contextMenuRemindComplete = document.getElementById("treechildren-contextmenu-remindUntilComplete");    
  4337.     if ( currentReminder.remindUntilCompleted != REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE) {
  4338.         contextMenuRemindComplete.setAttribute("checked", "true");     
  4339.     }
  4340.     else {
  4341.         contextMenuRemindComplete.setAttribute("checked", "false");     
  4342.     }
  4343.  
  4344.     var contextMenuComplete = document.getElementById("treechildren-contextmenu-markAsComplete");    
  4345.     if ( currentReminder.completedDate == null ) {
  4346.             contextMenuComplete.setAttribute("checked", "false");    
  4347.     }
  4348.     else {
  4349.         var treeChildren = document.getElementById("treechildren");
  4350.         var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  4351.         var reminderDateTime = selectedTreeItem.childNodes[0].getAttribute(REMINDER_DATE_REF);    
  4352.         var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  4353.  
  4354.         if ( reminderFox_isCompletedForDate( currentReminder, reminderInstanceDate ) )  {
  4355.                 contextMenuComplete.setAttribute("checked", "true");    
  4356.         }
  4357.         else {
  4358.             contextMenuComplete.setAttribute("checked", "false");    
  4359.         }
  4360.     }
  4361.         
  4362.     // If reminder is associated with an email, show the View Mail context menu item.  Otherwise, do not.
  4363.     var showMail = document.getElementById("treechildren-contextmenu-showMail");    
  4364.     if ( showMail != null ) {
  4365.         if ( currentReminder.messageID == null  ) {
  4366.             showMail.setAttribute("hidden", "true");    
  4367.         }
  4368.         else {
  4369.             showMail.setAttribute("hidden", "false");    
  4370.         }
  4371.     }
  4372.     
  4373.     if ( isSubscribedCalendarTabSelected() ) {  // disable some menu items for subscribed (read-only) calendars
  4374.         document.getElementById("treechildren-contextmenu-important").setAttribute( "disabled", true );
  4375.         document.getElementById("treechildren-contextmenu-markAsComplete").setAttribute( "disabled", true );
  4376.         document.getElementById("treechildren-contextmenu-remindUntilComplete").setAttribute( "disabled", true );
  4377.         document.getElementById("treechildren-contextmenu-delete").setAttribute( "disabled", true );
  4378.     }
  4379.     else {
  4380.         document.getElementById("treechildren-contextmenu-important").removeAttribute( "disabled" );
  4381.         document.getElementById("treechildren-contextmenu-markAsComplete").removeAttribute( "disabled" );
  4382.         document.getElementById("treechildren-contextmenu-remindUntilComplete").removeAttribute( "disabled" );
  4383.         document.getElementById("treechildren-contextmenu-delete").removeAttribute( "disabled" );
  4384.     }
  4385. }
  4386.  
  4387. function reminderFox_toggleReminderColumns(event){
  4388.       var row = {}, column = {}, part = {};
  4389.       var tree = document.getElementById("reminderTree");
  4390.       var boxobject = tree.boxObject;
  4391.       boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  4392.       boxobject.getCellAt(event.clientX, event.clientY, row, column, part);
  4393.  
  4394.     var rowIndex = row.value;
  4395.     if ( rowIndex != -1 && event.button != 2 ) {  // don't handle event if right-clicking (only show context menu)
  4396.         var  treeSelection = document.getElementById("reminderTree").view.selection;
  4397.                 
  4398.         if (typeof column.value != "string") {
  4399.             if ( column.value != null ) {
  4400.                   column.value = column.value.id;
  4401.             }
  4402.           }
  4403.  
  4404.         // cycler columns do not get selected automatically like other columns.  Must manually 
  4405.         // call select
  4406.         if ( column.value == "remindUntilCompletedColLabel" ) {
  4407.             treeSelection.select(rowIndex);
  4408.             toggleRemindUntilCompleted();
  4409.         }
  4410.         else if ( column.value == "CompleteColLabel" ) {
  4411.             treeSelection.select(rowIndex);
  4412.             toggleMarkAsComplete();
  4413.         }
  4414.         else if ( column.value == "mailColLabel" ) {
  4415.             treeSelection.select(rowIndex);
  4416.             reminderFox_doShowMail();
  4417.         }    
  4418.         else if ( column.value == "notesColLabel" ||
  4419.             column.value == "alarmColLabel" ) {
  4420.             treeSelection.select(rowIndex);  
  4421.         }            
  4422.         
  4423.     }
  4424. }
  4425.  
  4426. function reminderFox_toggleTodoColumns(event){
  4427.       var row = {}, column = {}, part = {};
  4428.       var tree = document.getElementById("todoTree");
  4429.       var boxobject = tree.boxObject;
  4430.       boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  4431.       boxobject.getCellAt(event.clientX, event.clientY, row, column, part);
  4432.  
  4433.     var rowIndex = row.value;
  4434.     if ( rowIndex != -1 && event.button != 2 ) {  // don't handle event if right-clicking (only show context menu)
  4435.         var  treeSelection = document.getElementById("todoTree").view.selection;        
  4436.         
  4437.         if (typeof column.value != "string") {
  4438.              column.value = column.value.id;
  4439.         }
  4440.     
  4441.         if ( column.value == "todoShowInTooltip" ) {
  4442.             treeSelection.select(rowIndex);
  4443.             toggleTodoShowInTooltip();
  4444.         }
  4445.         else if ( column.value == "todoCompleteColLabel" ) {
  4446.             treeSelection.select(rowIndex);
  4447.             toggleTodoMarkAsComplete();
  4448.         }
  4449.         else if ( column.value == "todoMailColLabel" ) {
  4450.             treeSelection.select(rowIndex);
  4451.             reminderFox_doShowMailTodo();
  4452.         }                
  4453.         else if ( column.value == "todoNotesColLabel" ||
  4454.             column.value == "todoAlarmColLabel" ) {
  4455.             treeSelection.select(rowIndex);  
  4456.         }            
  4457.     }
  4458. }
  4459.  
  4460. function getLabelForColumn( columnId ) {
  4461.     var column = document.getElementById(columnId);
  4462.     return  column.getAttribute("label");
  4463. }
  4464.  
  4465. function addTooltipWithLabel( tooltipItem, columnId, value, importantStatus, completedStatus, labelText) {
  4466.     var hbox = document.createElement("hbox");        
  4467.     var columnLabel;    
  4468.     if ( columnId == null ) {
  4469.         columnLabel = labelText;
  4470.     }
  4471.     else {
  4472.         columnLabel = getLabelForColumn(columnId);        
  4473.     }
  4474.     
  4475.     var title = document.createElement("description");
  4476.     title.setAttribute("value",columnLabel + ": ");
  4477.     title.setAttribute( "style", "font-weight:bold");
  4478.     hbox.appendChild( title );
  4479.     
  4480.     var tooltipValue = document.createElement("description");
  4481.     tooltipValue.setAttribute("value", value );
  4482.     
  4483.     if ( importantStatus && completedStatus ) {
  4484.         tooltipValue.setAttribute( "style", " text-decoration: line-through; color: red" );
  4485.     }
  4486.     else if ( importantStatus ) {
  4487.         tooltipValue.setAttribute( "style", "color: red" );
  4488.     }
  4489.     else if ( completedStatus ) {
  4490.         tooltipValue.setAttribute( "style", " text-decoration: line-through" );
  4491.     }
  4492.     
  4493.     hbox.appendChild( tooltipValue );
  4494.     
  4495.     tooltipItem.appendChild(hbox);        
  4496. }
  4497.  
  4498.  
  4499. function reminderTreeTooltip(event) {
  4500.      var tree = document.getElementById("reminderTree");
  4501.      var boxobject = tree.boxObject;
  4502.       boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);  // cast to treeboxobject to use getRowAt
  4503.   
  4504.       var row = {}, column = {}, part = {};
  4505.     boxobject.getCellAt(event.clientX, event.clientY, row, column, part);
  4506.        
  4507.     if (column.value != null && typeof column.value != "string") {
  4508.          column.value = column.value.id;
  4509.      }
  4510.  
  4511.     
  4512.      var index = tree.boxObject.getRowAt( event.clientX, event.clientY );
  4513.      if ( index == -1 ) {
  4514.          return false;  // returning false causes tooltip to not show
  4515.      }     
  4516.      var treeChildren = document.getElementById("treechildren");
  4517.      var selectedTreeItem = treeChildren.childNodes[index];
  4518.     var reminderRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  4519.     
  4520.     var reminder =  reminderFox_getRemindersById( reminderRefId, getCurrentReminderList() );
  4521.      if ( reminder == null ) {
  4522.          return false; // returning false causes tooltip to not show
  4523.      }
  4524.  
  4525.      var tooltipItem = document.getElementById("reminderTree-tooltip-box"); 
  4526.      while (tooltipItem.hasChildNodes()) {
  4527.              tooltipItem.removeChild(tooltipItem.firstChild);
  4528.        }     
  4529.        
  4530.        // if this is the alarm column, show the alarm value
  4531.     if ( reminder.alarm != null && column.value == "alarmColLabel" ) { 
  4532.         // if the alarm is currently snoozed, show the snooze value as well....    
  4533.         if ( reminder.snoozeTime != null ) { 
  4534.             var snoozeAlarmTime = reminder.snoozeTime;
  4535.             var index = snoozeAlarmTime.indexOf( ';' );
  4536.             if ( index != -1 ) {
  4537.                 snoozeAlarmTime = snoozeAlarmTime.substring( 0, index );                
  4538.             }        
  4539.             var snoozedate = new Date( parseInt(snoozeAlarmTime));    
  4540.             var dateString = reminderFox_getDateVariableString( reminder, snoozedate);
  4541.             var timeString = reminderFox_mail_getTimeString(snoozedate);
  4542.                     
  4543.             var snoozetitle = document.createElement("description");
  4544.             snoozetitle.setAttribute("value",  g_reminderFoxBundle.getString("rf.alarm.list.tooltip.snooze")  + " " + dateString + ", " + timeString);  
  4545.             tooltipItem.appendChild(snoozetitle);    
  4546.         }
  4547.         else {  
  4548.             // otherwise show when the next alarm is scheduled for...
  4549.             var reminderDateTime = selectedTreeItem.childNodes[0].getAttribute(REMINDER_DATE_REF);    
  4550.             var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  4551.             
  4552.             var newDate = new Date( reminder.date.getFullYear(), reminder.date.getMonth(), reminder.date.getDate(), 
  4553.                 reminder.date.getHours(), reminder.date.getMinutes() );
  4554.             if ( reminder.allDayEvent ) {
  4555.                 newDate.setHours( 0, 0 );
  4556.             }
  4557.             var mins =     newDate.getMinutes();
  4558.             var alarmMinutes = reminderFox_getAlarmInMinutes( reminder.alarm );
  4559.             if ( alarmMinutes != null ) { 
  4560.                 newDate.setMinutes( mins - alarmMinutes );
  4561.                 
  4562.                 var dateString = reminderFox_getDateVariableString( reminder, newDate);
  4563.                 var timeString = reminderFox_mail_getTimeString(newDate);
  4564.                         
  4565.                 var snoozetitle = document.createElement("description");
  4566.                 snoozetitle.setAttribute("value",  g_reminderFoxBundle.getString("rf.alarm.tooltip.text")   + " " + dateString + ", " + timeString);   
  4567.                 tooltipItem.appendChild(snoozetitle);    
  4568.             }
  4569.         }
  4570.         
  4571.         // add the alarm value to the tooltip  (eg: "alarm: 15 minutes before event")
  4572.         var title = document.createElement("description");
  4573.         title.setAttribute("value", getAlarmTooltipText( reminder.alarm ));
  4574.         tooltipItem.appendChild(title);    
  4575.     }
  4576.     else {                   
  4577.         var row = selectedTreeItem.childNodes[0];
  4578.         var dateCell = row.childNodes[0];
  4579.         var dateCellLabel = dateCell.getAttribute("label");        
  4580.         var descCell = row.childNodes[1];
  4581.         var descCellLabel = descCell.getAttribute("label");
  4582.         var timeCell = row.childNodes[2];
  4583.         var timeCellLabel = timeCell.getAttribute("label");            
  4584.         var completedDateNode = selectedTreeItem.childNodes[0].childNodes[3];    
  4585.         var completedDateLabel = completedDateNode.getAttribute( "label");
  4586.     
  4587.         var important = false;
  4588.         if ( reminder.priority == REMINDER_PRIORITY_IMPORTANT ) {
  4589.             important = true;
  4590.         }
  4591.         
  4592.         // see if current instance of reminder is completed
  4593.         var completed = false;    
  4594.         var reminderDateTime = row.getAttribute(REMINDER_DATE_REF);    
  4595.         var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  4596.         
  4597.         if  ( reminderFox_isCompletedForDate( reminder, reminderInstanceDate )  ) {
  4598.             completed = true;
  4599.         }  
  4600.         
  4601.         addTooltipWithLabel( tooltipItem, "descColLabel", descCellLabel, important, completed );
  4602.         
  4603.         var dateString = dateCellLabel;
  4604.         if ( !reminder.allDayEvent ) {
  4605.             dateString = dateString + ", " + timeCellLabel;
  4606.         }
  4607.         
  4608.         if ( reminder.durationTime != null ) {
  4609.             var reminderInstanceEndDate = new Date(parseInt(reminderDateTime) + reminder.durationTime);        
  4610.             if ( reminder.allDayEvent ) {
  4611.                 if (reminder.durationTime >86400000 ) {   // 24 * 60 * 60 * 1000 = 1 day in ms
  4612.                     reminderInstanceEndDate.setDate( reminderInstanceEndDate.getDate() - 1); // -1 enddate offset
  4613.                     var endDateStr = reminderFox_getDateVariableString( reminder, reminderInstanceEndDate);
  4614.                     dateString += " - " +  endDateStr;
  4615.                 }
  4616.             }
  4617.             else {
  4618.                 var endTime = reminderFox_mail_getTimeString(reminderInstanceEndDate);
  4619.                 if (reminderInstanceEndDate.getMonth() == reminderInstanceDate.getMonth() &&
  4620.                     reminderInstanceEndDate.getDate() == reminderInstanceDate.getDate() ) {
  4621.                     // same days.. 
  4622.                     dateString += " - " +  endTime;
  4623.                 }
  4624.                 // multiple days
  4625.                 else { 
  4626.                     var endDateStr = reminderFox_getDateVariableString( reminder, reminderInstanceEndDate);
  4627.                     dateString += " - " +  endDateStr + ", " + endTime;
  4628.                 }
  4629.             }
  4630.         }
  4631.         
  4632.         
  4633.         addTooltipWithLabel( tooltipItem, "dateColLabel", dateString );
  4634.         
  4635.         if ( reminder.categories != null && reminder.categories != "" ) {            
  4636.             addTooltipWithLabel( tooltipItem, "catColLabel", reminder.categories );
  4637.         }
  4638.         
  4639.         if ( completedDateLabel != null && completedDateLabel != "" ) {        
  4640.             addTooltipWithLabel( tooltipItem, "dateCompleted", completedDateLabel );
  4641.         }
  4642.         
  4643.         if ( reminder.location != null && reminder.location != "" ) {            
  4644.             addTooltipWithLabel( tooltipItem, null, reminder.location, false, false, g_reminderFoxBundle.getString("rf.add.reminders.tooltip.locaton") );  
  4645.         }
  4646.         
  4647.         if ( reminder.url != null && reminder.url != "" ) {            
  4648.             addTooltipWithLabel( tooltipItem, null, reminder.url, false, false, g_reminderFoxBundle.getString("rf.add.reminders.tooltip.url") );
  4649.         }                
  4650.                 
  4651.         // add notes to to tooltip (if applicable)        
  4652.         //                
  4653.          if ( reminder.notes != null ) {
  4654.                addNotesToTooltip( reminder.notes, tooltipItem );
  4655.        }
  4656.     }
  4657.    return true;
  4658. }
  4659.  
  4660.  
  4661. function todoTreeTooltip(event) {
  4662.      var tree = document.getElementById("todoTree");
  4663.      var boxobject = tree.boxObject;
  4664.       boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);  // cast to treeboxobject to use getRowAt
  4665.       //boxobject.getCellAt(event.clientX, event.clientY, row, column, part);
  4666.  
  4667.     var row = {}, column = {}, part = {};
  4668.     boxobject.getCellAt(event.clientX, event.clientY, row, column, part);
  4669.     
  4670.     if (column.value != null && typeof column.value != "string") {
  4671.          column.value = column.value.id;  
  4672.      }
  4673.   
  4674.      var index = tree.boxObject.getRowAt( event.clientX, event.clientY );
  4675.      if ( index == -1 ) {
  4676.          return false; // returning false causes tooltip to not show
  4677.      }
  4678.      var treeChildren = document.getElementById("todoTreechildren");
  4679.      var selectedTreeItem = treeChildren.childNodes[index];
  4680.     var todoRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  4681.     var todo =  reminderFox_getTodosById( todoRefId,  getCurrentTodoList() );
  4682.      if ( todo == null ) {
  4683.          return false; // returning false causes tooltip to not show
  4684.      }
  4685.      
  4686.      todo = reminderFox_processReminderDescription(todo,  new Date().getFullYear(), true );    
  4687.      
  4688.  
  4689.       var tooltipItem = document.getElementById("todoTree-tooltip-box"); 
  4690.      while (tooltipItem.hasChildNodes()) {
  4691.              tooltipItem.removeChild(tooltipItem.firstChild);
  4692.        }     
  4693.      
  4694.      // if this is the alarm column, show the alarm value
  4695.     if ( todo.alarm != null && column != null && column.value == "todoAlarmColLabel" ) { 
  4696.         // if the alarm is currently snoozed, show the snooze value as well....    
  4697.         if ( todo.snoozeTime != null ) { 
  4698.             var snoozeAlarmTime = todo.snoozeTime;
  4699.             var index = snoozeAlarmTime.indexOf( ';' );
  4700.             if ( index != -1 ) {
  4701.                 snoozeAlarmTime = snoozeAlarmTime.substring( 0, index );                
  4702.             }        
  4703.             var snoozedate = new Date( parseInt(snoozeAlarmTime));    
  4704.             var dateString = reminderFox_getDateVariableString( todo, snoozedate);
  4705.             var timeString = reminderFox_mail_getTimeString(snoozedate);
  4706.  
  4707.             var snoozetitle = document.createElement("description");
  4708.             snoozetitle.setAttribute("value",  g_reminderFoxBundle.getString("rf.alarm.list.tooltip.snooze")  + " " + dateString + ", " + timeString);  
  4709.             tooltipItem.appendChild(snoozetitle);    
  4710.         }
  4711.         
  4712.         // add the alarm to the tooltip
  4713.         var title = document.createElement("description");
  4714.         title.setAttribute("value", getAlarmTooltipText( todo.alarm ));
  4715.         tooltipItem.appendChild(title);        
  4716.           
  4717.         
  4718.         
  4719.         
  4720.     }
  4721.     else {        
  4722.         var row = selectedTreeItem.childNodes[0];
  4723.         var dateCell = row.childNodes[0];
  4724.         var dateCellLabel = dateCell.getAttribute("label");        
  4725.         var descCell = row.childNodes[1];
  4726.         var descCellLabel = descCell.getAttribute("label");
  4727.         var timeCell = row.childNodes[2];
  4728.         var timeCellLabel = timeCell.getAttribute("label");    
  4729.         var completedDateNode = selectedTreeItem.childNodes[0].childNodes[3];    
  4730.         var completedDateLabel = completedDateNode.getAttribute( "label");
  4731.         
  4732.         var important = false;
  4733.         if ( todo.priority == REMINDER_PRIORITY_IMPORTANT ) {
  4734.             important = true;
  4735.         }
  4736.         var completed = false;
  4737.         if  ( todo.completedDate != null  ) {
  4738.             completed = true;
  4739.         }
  4740.         addTooltipWithLabel( tooltipItem, "descColLabel", descCellLabel, important, completed );
  4741.     
  4742.         if ( todo.date != null ) {
  4743.             var dateString = dateCellLabel;
  4744.             if ( !todo.allDayEvent ) {
  4745.                 dateString = dateString + ", " + timeCellLabel;
  4746.             }
  4747.             
  4748.             if ( todo.durationTime != null ) {
  4749.                 var reminderDateTime = row.getAttribute(REMINDER_DATE_REF);    
  4750.                 if ( reminderDateTime != null ) {
  4751.                     var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  4752.                     var reminderInstanceEndDate = new Date(parseInt(reminderDateTime) + todo.durationTime);        
  4753.                     if ( todo.allDayEvent ) {
  4754.                         if (todo.durationTime >86400000 ) {   // 24 * 60 * 60 * 1000 = 1 day in ms
  4755.                             reminderInstanceEndDate.setDate( reminderInstanceEndDate.getDate() - 1); // -1 enddate offset
  4756.                             var endDateStr = reminderFox_getDateVariableString( todo, reminderInstanceEndDate);
  4757.                             dateString += " - " +  endDateStr;
  4758.                         }
  4759.                     }
  4760.                     else {
  4761.                         var endTime = reminderFox_mail_getTimeString(reminderInstanceEndDate);
  4762.                         if (reminderInstanceEndDate.getMonth() == reminderInstanceDate.getMonth() &&
  4763.                             reminderInstanceEndDate.getDate() == reminderInstanceDate.getDate() ) {
  4764.                             // same days.. 
  4765.                             dateString += " - " +  endTime;
  4766.                         }
  4767.                         // multiple days
  4768.                         else { 
  4769.                             var endDateStr = reminderFox_getDateVariableString( todo, reminderInstanceEndDate);
  4770.                             dateString += " - " +  endDateStr + ", " + endTime;
  4771.                         }
  4772.                     }
  4773.                 }
  4774.             }
  4775.             
  4776.             
  4777.             addTooltipWithLabel( tooltipItem, "dateColLabel", dateString );
  4778.         }
  4779.         
  4780.         if ( todo.categories != null && todo.categories != "" ) {            
  4781.             addTooltipWithLabel( tooltipItem, "catColLabel", todo.categories );
  4782.         }
  4783.         
  4784.         if ( completedDateLabel != null && completedDateLabel != "" ) {        
  4785.             addTooltipWithLabel( tooltipItem, "todoDateCompleted", completedDateLabel );
  4786.         }
  4787.         
  4788.         if ( todo.location != null && todo.location != "" ) {            
  4789.             addTooltipWithLabel( tooltipItem, null, todo.location, false, false, g_reminderFoxBundle.getString("rf.add.reminders.tooltip.locaton") );  
  4790.         }
  4791.         
  4792.         if ( todo.url != null && todo.url != "" ) {            
  4793.             addTooltipWithLabel( tooltipItem, null, todo.url, false, false, g_reminderFoxBundle.getString("rf.add.reminders.tooltip.url") );
  4794.         }                
  4795.                 
  4796.         // add notes to to tooltip (if applicable)        
  4797.         //                
  4798.          if ( todo.notes != null ) {
  4799.                addNotesToTooltip( todo.notes, tooltipItem );
  4800.        }                   
  4801.     }
  4802.  
  4803.    return true;
  4804. }
  4805.  
  4806. function addNotesToTooltip( orignotes, tooltipItem, maxLines ) {
  4807.      var newline = "\n";
  4808.      
  4809.      // replace all tab characters with spaces (otherwise shows up as weird character)
  4810.      var notes = orignotes.replace(new RegExp(/\t/g),"    ");  
  4811.      //var columnLabel = getLabelForColumn( "notesColLabel");
  4812.     var separatedString = notes.split(newline);    
  4813.     var tooltipWrapLength = 120;
  4814.     var remLabel;
  4815.     var headerAdded = false;
  4816.     var maxLinesReached = false;
  4817.     var numberOfLinesAdded = 0;
  4818.     for ( var i = 0; i < separatedString.length && !maxLinesReached; i++ ) {
  4819.         var noteLine = separatedString[i];
  4820.         while ( noteLine.length > tooltipWrapLength && !maxLinesReached ) {        
  4821.             // go back to last whitespace
  4822.             var lastIndex = noteLine.lastIndexOf( ' ', tooltipWrapLength );
  4823.             var forceLineBreak = false;
  4824.             if ( lastIndex == -1 ) {
  4825.                 forceLineBreak = true;
  4826.                 lastIndex = tooltipWrapLength + 1;
  4827.             }
  4828.             if ( lastIndex != -1 ) {
  4829.                 var curStr = noteLine.substring( 0, lastIndex );                                           
  4830.                 if ( !headerAdded ) { // first row, add column header name                
  4831.                     addTooltipWithLabel( tooltipItem, "notesColLabel", curStr );
  4832.                     numberOfLinesAdded++;
  4833.                     headerAdded = true;
  4834.                 }       
  4835.                 else {
  4836.                     remLabel = document.createElement("description");        
  4837.                     remLabel.setAttribute("value", curStr);
  4838.                     tooltipItem.appendChild(remLabel);
  4839.                     numberOfLinesAdded++;
  4840.                     if ( maxLines != null && numberOfLinesAdded >= maxLines ) {
  4841.                         maxLinesReached = true;
  4842.                     }
  4843.                 }
  4844.             }
  4845.             var startIndex;
  4846.             if ( forceLineBreak ) {
  4847.                 startIndex = lastIndex;
  4848.             }
  4849.             else {
  4850.                 startIndex = lastIndex + 1;
  4851.             }
  4852.             noteLine = noteLine.substring( startIndex );                                                  
  4853.         }            
  4854.  
  4855.         if ( !headerAdded ) { // first row, add column header name                
  4856.             addTooltipWithLabel( tooltipItem, "notesColLabel", noteLine );
  4857.             numberOfLinesAdded++;
  4858.             headerAdded = true;
  4859.         }            
  4860.         else {
  4861.             remLabel = document.createElement("description");
  4862.             remLabel.setAttribute("value", noteLine);
  4863.             tooltipItem.appendChild(remLabel);
  4864.             
  4865.             numberOfLinesAdded++;
  4866.             if ( maxLines != null && numberOfLinesAdded >= maxLines ) {
  4867.                 maxLinesReached = true;
  4868.             }
  4869.         }
  4870.     }
  4871.     
  4872.     // notes are truncated - add indicator
  4873.     if ( maxLinesReached ) {
  4874.            var notesTruncatedLabel = document.createElement("description");
  4875.         notesTruncatedLabel.setAttribute("value", "...");
  4876.         tooltipItem.appendChild(notesTruncatedLabel);
  4877.     }
  4878.         
  4879. }                           
  4880.  
  4881. function userMoveTodoToReminderList(eventTarget) {
  4882.     var selectedTodos = getAllSelectedTodos();
  4883.     for ( var i = 0; i < selectedTodos.length; i++ ) {        
  4884.         var movedTodo = selectedTodos[i];    
  4885.  
  4886.         var newReminder = reminderFox_convertTodoToReminder( movedTodo);
  4887.         
  4888.         removeTodo(movedTodo);
  4889.     
  4890.         // add reminder in sorted order...
  4891.         var reminders = reminderFox_getReminderEvents();                
  4892.         var sortedIndex = reminderFox_getSortedIndexOfNewReminder( reminders, newReminder, false );
  4893.         reminderFox_insertIntoArray( reminders, newReminder, sortedIndex );
  4894.     
  4895.         createListItem(newReminder);  // update UI list
  4896.     }
  4897.     refreshCalendar();
  4898.  
  4899.     modifiedReminders();            
  4900. }
  4901.  
  4902. function getAlarmTooltipText( alarmTime)  {     
  4903.     var result;
  4904.     var alarmIndex1 = alarmTime.indexOf( "-PT" );
  4905.     if ( alarmIndex1 != -1 ) {
  4906.         var alarmIndex2 = alarmTime.indexOf( "M", alarmIndex1 );
  4907.         if ( alarmIndex2 != -1 ) {
  4908.             alarmTime = alarmTime.substring( alarmIndex1 + "-PT".length, alarmIndex2 );        
  4909.             result = "(" + g_reminderFoxBundle.getString("rf.reminderoptions.alarm")  + ": " + 
  4910.                  alarmTime + " " + g_reminderFoxBundle.getString("rf.reminderoptions.notify.minutes.label") + " " +
  4911.                  g_reminderFoxBundle.getString("rf.reminderoptions.notify.before.label") + ")";
  4912.                  
  4913.         }
  4914.         else {
  4915.             alarmIndex2 = alarmTime.indexOf( "H", alarmIndex1 );
  4916.             if ( alarmIndex2 != -1 ) {
  4917.                 alarmTime = alarmTime.substring( alarmIndex1 + "-PT".length, alarmIndex2 );        
  4918.                 result = "(" + g_reminderFoxBundle.getString("rf.reminderoptions.alarm")  + ": " + 
  4919.                      alarmTime + " " + g_reminderFoxBundle.getString("rf.reminderoptions.notify.hours.label") + " " +
  4920.                      g_reminderFoxBundle.getString("rf.reminderoptions.notify.before.label") + ")";
  4921.             }    
  4922.         }    
  4923.     }
  4924.     else {
  4925.         alarmIndex1 = alarmTime.indexOf( "-P" );
  4926.         if ( alarmIndex1 != -1 ) {
  4927.             var alarmIndex2 = alarmTime.indexOf( "D", alarmIndex1 );
  4928.             if ( alarmIndex2 != -1 ) {
  4929.                 alarmTime = alarmTime.substring( alarmIndex1 + "-P".length, alarmIndex2 );        
  4930.                 result = parseInt( alarmTime ) * 24 * 60;    
  4931.                 result = "(" + g_reminderFoxBundle.getString("rf.reminderoptions.alarm")  + ": " + 
  4932.                      alarmTime + " " + g_reminderFoxBundle.getString("rf.reminderoptions.notify.days.label") + " " +
  4933.                      g_reminderFoxBundle.getString("rf.reminderoptions.notify.before.label") + ")";
  4934.             }
  4935.          }
  4936.     }        
  4937.     return result;
  4938. }
  4939.  
  4940. function userMoveToTodoList(eventTarget) {
  4941.     var targetTodoListName =  eventTarget.getAttribute( "label" );
  4942.  
  4943.     var selectedTodos = getAllSelectedTodos();
  4944.     for ( var i = 0; i < selectedTodos.length; i++ ) {        
  4945.         var movedTodo = selectedTodos[i];        
  4946.     
  4947.         if ( movedTodo.date != null ) { // could want to move to a reminder
  4948.             var tabList = document.getElementById("tabList");    
  4949.             var tablistItem = tabList.childNodes[0];      // get first tab (reminders)
  4950.             var tabLabel = tablistItem.getAttribute("label");        
  4951.             
  4952.             if ( tabLabel == targetTodoListName) {
  4953.                 userMoveTodoToReminderList(eventTarget);
  4954.                 return;
  4955.             }
  4956.         }    
  4957.         // if moving to ToDo's, use special "ToDo's" id (as label could be another language)
  4958.         var tabList = document.getElementById("tabList");    
  4959.         var tablistItem = tabList.childNodes[1];      // get second tab -- "ToDo's"
  4960.         var tabLabel = tablistItem.getAttribute("label");        
  4961.         if ( tabLabel == targetTodoListName) {
  4962.             targetTodoListName = REMINDER_FOX_DEFAULT_TODOS_CATEGORY;
  4963.         }    
  4964.             
  4965.         var todosArr =    reminderFox_getReminderTodos();
  4966.         var todos = todosArr[targetTodoListName];
  4967.         if ( todos == null ) {
  4968.             todos = new Array();
  4969.             todosArr[targetTodoListName] = todos;
  4970.         }    
  4971.         removeTodo(movedTodo);
  4972.         var sortedIndex = reminderFox_getSortedIndexOfNewTodo(todos, movedTodo );
  4973.         reminderFox_insertIntoArray( todos, movedTodo, sortedIndex );
  4974.     }
  4975.     refreshCalendar();
  4976.       modifiedReminders();
  4977. }
  4978.  
  4979. function activateTodoContext(event) {
  4980.     var tree = document.getElementById("todoTree");
  4981.     document.popupNode = tree;
  4982.     
  4983.     var selectedTreeItemIndex = document.getElementById("todoTree").currentIndex;
  4984.     var treeChildren = document.getElementById("todoTreechildren");
  4985.     var contextMenu = document.getElementById("todo-treechildren-contextmenu");    
  4986.     var currentTodo = getTodoForSelectedItem( );
  4987.     if ( treeChildren == null || selectedTreeItemIndex == -1 || treeChildren.childNodes.length == 0 || currentTodo == null ) {
  4988.         for ( var i = 0; i < contextMenu.childNodes.length; i++ ) {
  4989.             contextMenu.childNodes[i].setAttribute( "disabled", true );
  4990.         }
  4991.         return;
  4992.     }
  4993.     else { 
  4994.         // enable all child menu items
  4995.         for ( var i = 0; i < contextMenu.childNodes.length; i++ ) {
  4996.             contextMenu.childNodes[i].removeAttribute( "disabled" );
  4997.         }        
  4998.     }
  4999.     
  5000.     
  5001.     var multipleTodosSelected = false;
  5002.     var selectedTodos = getAllSelectedTodos();
  5003.     if ( selectedTodos.length > 1 ) { 
  5004.         multipleTodosSelected = true;
  5005.     }
  5006.     
  5007.     var treechildrenContextmenuEdit = document.getElementById("treechildren-contextmenu-edit2");    
  5008.     if ( multipleTodosSelected ) { 
  5009.         // if multiple reminders selected, disable Edit        
  5010.         treechildrenContextmenuEdit.setAttribute( "disabled", true );
  5011.     }
  5012.     else {
  5013.             treechildrenContextmenuEdit.removeAttribute( "disabled" );
  5014.     }
  5015.     
  5016.     
  5017.     // show current lists...
  5018.     var moveToList = document.getElementById("treechildren-contextmenu-moveToList-popup");    
  5019.     while (moveToList.hasChildNodes()) {
  5020.          moveToList.removeChild(moveToList.firstChild);
  5021.     }
  5022.     var tabList = document.getElementById("tabList");    
  5023.     var tab =    tabList.selectedItem;
  5024.     var tabIndex =    tabList.selectedIndex;
  5025.  
  5026.     var index = tab.id.indexOf( ':' );
  5027.     if ( tabIndex <= 1 || index == -1 ) {
  5028.         name = REMINDER_FOX_DEFAULT_TODOS_CATEGORY;
  5029.     }
  5030.     else {
  5031.         name = tab.id.substring( index +1 , tab.id.length );
  5032.     }
  5033.     
  5034.     var i = 0;
  5035.     if ( currentTodo.date == null ) {
  5036.         i = 1;   // if no date on the ToDo, don't allow to move to a reminder
  5037.     }
  5038.     var subscriptions = reminderFox_getSubscriptions();
  5039.     for ( ; i < tabList.childNodes.length; i++ ) {  
  5040.         var tablistItem = tabList.childNodes[i];    
  5041.         var tabLabel = tablistItem.getAttribute("label");
  5042.         if ( tabLabel != name &&  subscriptions[tabLabel] == null ) {  // ignore subscribed calendars
  5043.             var menuItem = document.createElement("menuitem");
  5044.             menuItem.setAttribute( "label", tabLabel );
  5045.             menuItem.setAttribute( "oncommand", "userMoveToTodoList(event.target)");
  5046.             moveToList.appendChild(menuItem);
  5047.         }
  5048.     }    
  5049.     
  5050.     // modify context menu depending on Important reminder status
  5051.     var contextMenuImportant = document.getElementById("treechildren-contextmenu-important2");    
  5052.     if ( currentTodo.priority != REMINDER_PRIORITY_IMPORTANT ) {
  5053.         contextMenuImportant.setAttribute("checked", "false");    
  5054.     }
  5055.     else {
  5056.         contextMenuImportant.setAttribute("checked", "true");    
  5057.     }    
  5058.     
  5059.     var contextMenuComplete = document.getElementById("treechildren-contextmenu-markAsComplete2");    
  5060.     if ( currentTodo.completedDate != null  ) {
  5061.             contextMenuComplete.setAttribute("checked", "true");    
  5062.     }
  5063.     else {
  5064.         contextMenuComplete.setAttribute("checked", "false");    
  5065.     }    
  5066.  
  5067.  
  5068.     var contextMenuShowInTooltip = document.getElementById("treechildren-contextmenu-showInTooltip");    
  5069.     if ( currentTodo.showInTooltip ) {
  5070.         contextMenuShowInTooltip.setAttribute("checked", "true");    
  5071.     }
  5072.     else {
  5073.         contextMenuShowInTooltip.setAttribute("checked", "false");    
  5074.     }
  5075.  
  5076.     // disable moveUp/moveDown if that option isn't available
  5077.     var moveUpMenu = document.getElementById("treechildren-contextmenu-moveUp");        
  5078.  
  5079.     var isFirst =     isFirstTodoSelected();
  5080.     if ( isFirst ) {
  5081.         moveUpMenu.setAttribute( "disabled", true );
  5082.     }
  5083.     else {
  5084.         moveUpMenu.setAttribute( "disabled", false );
  5085.     }
  5086.     
  5087.     var moveDownMenu = document.getElementById("treechildren-contextmenu-moveDown");    
  5088.     if ( isLastTodoSelected() ) {
  5089.         moveDownMenu.setAttribute( "disabled", true );
  5090.     }
  5091.     else {
  5092.         moveDownMenu.setAttribute( "disabled", false );
  5093.     }
  5094.     
  5095.     // If reminder is associated with an email, show the View Mail context menu item.  Otherwise, do not.
  5096.     var showMail = document.getElementById("treechildren-contextmenu-showMail2");    
  5097.     if ( showMail != null ) {
  5098.         if ( currentTodo.messageID == null  ) {
  5099.             showMail.setAttribute("hidden", "true");    
  5100.         }
  5101.         else {
  5102.             showMail.setAttribute("hidden", "false");    
  5103.         }
  5104.     }    
  5105.         
  5106. }
  5107.  
  5108.  
  5109. function processKeyPressedOnReminderTree(event) {
  5110.     if (event.keyCode == 46)   // delete key
  5111.         userDeleteReminder();
  5112.     else if (event.keyCode == 13) // return
  5113.         editReminder();
  5114.     else if (event.charCode == 32) {    // space bar
  5115.         // fun note: if I don't call this in a settimeout, this will crash firefox (yay!).  This 
  5116.         // happens if you have a column sorted and hit the spacebar to run this evnet.  
  5117.         // In createListItemSorted when it is adding the elements for the tree item, after 
  5118.         // 10 attributes it crashes.  No idea why.  
  5119.         setTimeout( toggleMarkAsComplete, 1 );    
  5120.     }        
  5121. }
  5122.  
  5123. function processKeyPressedOnTodoTree(event) {
  5124.     if (event.keyCode == 46)   // delete key
  5125.         userDeleteTodo();
  5126.     else if (event.keyCode == 13)  // return
  5127.         editTodo();
  5128.     else if (event.charCode == 32) {    // space bar
  5129.         setTimeout( toggleTodoMarkAsComplete, 1 );    
  5130.     }
  5131. }
  5132.  
  5133.  
  5134.  
  5135. function editReminder() {
  5136.     var selectedTreeItemIndex = document.getElementById("reminderTree").currentIndex;
  5137.     var treeChildren = document.getElementById("treechildren");
  5138.       
  5139.     if ( selectedTreeItemIndex == -1 ) {
  5140.         return;
  5141.     }
  5142.     
  5143.     var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  5144.     if (  selectedTreeItem == null ) {
  5145.         return;
  5146.     }
  5147.  
  5148.     var currentReminder = getReminderForSelectedItem(); 
  5149.     var originalReminder = reminderFox_cloneReminderFoxEvent(currentReminder);
  5150.  
  5151.     var newOptions = { reminder: currentReminder, editing:  true,  addReminder: false, showMail: false,  readonly: isSubscribedCalendarTabSelected() };
  5152.     window.openDialog("chrome://reminderfox/content/editing/reminderOptionsDialog.xul",
  5153.             "window:reminderFoxReminderOptionsDialog", "chrome,resizable,modal", newOptions);
  5154.  
  5155. //   3.2.2.1 Rescheduling an Event:
  5156. //   A rescheduled event involves time or recurrence intervals 
  5157. //   and possibly the location or description
  5158.     rmFx_iCalReschedule(originalReminder, currentReminder);
  5159.     
  5160.     if ( newOptions.showMail ) {             
  5161.         reminderFox_displayMailbyMsgID(currentReminder);    
  5162.         editReminder();
  5163.         return;
  5164.     }
  5165.  
  5166.     if ( newOptions.addReminder ) {
  5167.         currentReminder = newOptions.reminder;
  5168.         
  5169.         if ( originalReminder.date.getFullYear() != currentReminder.date.getFullYear() ||
  5170.             originalReminder.date.getMonth() != currentReminder.date.getMonth() ||
  5171.             originalReminder.date.getDate() != currentReminder.date.getDate() ||
  5172.             originalReminder.date.getHours() != currentReminder.date.getHours() ||
  5173.             originalReminder.date.getMinutes() != currentReminder.date.getMinutes() ||  
  5174.             originalReminder.recurrence.endDate != currentReminder.recurrence.endDate || 
  5175.             originalReminder.recurrence.byDay !=  currentReminder.recurrence.byDay || 
  5176.             originalReminder.recurrence.interval != currentReminder.recurrence.interval ) {
  5177.                 // if the date has changed (or recurrence), treat as a new reminder.  This is because 
  5178.                 // We want to re-add in the proper sorted order into the list of reminders
  5179.                 
  5180.                 removeListItemsForReminder(originalReminder); 
  5181.                 // remove from model list
  5182.                 var reminders = reminderFox_getReminderEvents();    
  5183.                 for( var i = 0; i < reminders.length; i++) {
  5184.                     if ( reminders[i].id == originalReminder.id ) {
  5185.                         reminderFox_removeElement(reminders, i);
  5186.                         break;
  5187.                     }
  5188.                 }
  5189.     
  5190.                 // add reminder in sorted order...
  5191.                 reminders = reminderFox_getReminderEvents();                    
  5192.                 if ( currentReminder.remindUntilCompleted != REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE ) {
  5193.                      currentReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED;
  5194.                  }                
  5195.                 var sortedIndex = reminderFox_getSortedIndexOfNewReminder( reminders, currentReminder, false );
  5196.                 reminderFox_insertIntoArray( reminders, currentReminder, sortedIndex );
  5197.                 
  5198.                 currentReminder.snoozeTime = null;              
  5199.                 createListItem(currentReminder);            
  5200.             }
  5201.             // if the recurrence has changed, then we want to update the list as the dates may have 
  5202.             // changed
  5203.             else     if ( originalReminder.recurrence.type != currentReminder.recurrence.type ) {
  5204.                 removeListItemsForReminder(originalReminder);
  5205.                 createListItem(currentReminder);            
  5206.             }
  5207.         
  5208.             var currentDate = oeDatePicker.gSelectedDate;
  5209.             if ( currentDate == null ) {
  5210.                 currentDate = new Date();
  5211.             }    
  5212.             
  5213.             var newDate = new Date();
  5214.             if ( currentReminder.alarm != null ) {
  5215.                 currentReminder.alarmLastAcknowledge = newDate.getTime();
  5216.                 // if there's a snooze... and lastack > snooze, erase snooze...  this means...  well it should be if date changed at all, then need to clear snooze...
  5217.             }
  5218.             currentReminder.lastModified = reminderFox_getDateAsString(newDate );
  5219.             var reminder = reminderFox_processReminderDescription(currentReminder,  currentDate.getFullYear(), false);        
  5220.             var modified = updateReminderInList( reminder );
  5221.             sortReminderIfNeccessary( currentReminder.id); 
  5222.  
  5223.             refreshCalendar(false, true);
  5224.             modifiedReminders();
  5225.         }
  5226. }
  5227.  
  5228. function reminderFox_copyReminder(originalReminder, isTodo) {
  5229.     var currentDate = new Date();
  5230.     var newReminderFoxEvent = null;
  5231.     if ( !isTodo ) {
  5232.         newReminderFoxEvent = reminderFox_cloneReminderFoxEvent(originalReminder);
  5233.     }
  5234.     else {
  5235.         newReminderFoxEvent = reminderFox_cloneReminderFoxTodo(originalReminder);
  5236.     }
  5237.     var newId =reminderFox_generateUniqueReminderId(currentDate );
  5238.     newReminderFoxEvent.id =newId;
  5239.     newReminderFoxEvent.completedDate = null;
  5240.     newReminderFoxEvent.snoozeTime = null;
  5241.     if ( newReminderFoxEvent.alarm != null ) {
  5242.         newReminderFoxEvent.alarmLastAcknowledge = currentDate.getTime();
  5243.     }
  5244.     newReminderFoxEvent.lastModified = reminderFox_getDateAsString(currentDate );
  5245.     
  5246.     if ( newReminderFoxEvent.remindUntilCompleted ==  REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED ) { 
  5247.         newReminderFoxEvent.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED;
  5248.     }
  5249.     
  5250.     return newReminderFoxEvent;
  5251.     
  5252. }
  5253.  
  5254. function copyReminder() {
  5255.     var selectedTreeItemIndex = document.getElementById("reminderTree").currentIndex;
  5256.     var treeChildren = document.getElementById("treechildren");
  5257.       
  5258.     if ( selectedTreeItemIndex == -1 ) {
  5259.         return;
  5260.     }
  5261.     
  5262.     var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  5263.     if (  selectedTreeItem == null ) {
  5264.         return;
  5265.     }
  5266.  
  5267.     var currentReminder = getReminderForSelectedItem(); 
  5268.     
  5269.     var newCopyOfReminder = reminderFox_copyReminder( currentReminder );
  5270.     
  5271.     addReminder( true, newCopyOfReminder );
  5272. }
  5273.  
  5274. function copyTodo() {
  5275.     var currentTodo = getTodoForSelectedItem( );
  5276.     if ( currentTodo == null ) {
  5277.         return;
  5278.     }
  5279.     
  5280.     var newCopyOfTodo = reminderFox_copyReminder( currentTodo , true);
  5281.     
  5282.     addTodo( true, newCopyOfTodo );
  5283. }
  5284.  
  5285. function userDeleteReminder() {
  5286.     var selectedReminders = getAllSelectedReminders();
  5287.     
  5288.     if ( selectedReminders.length == 1 && 
  5289.              (selectedReminders[0].recurrence.type == REMINDER_RECURRENCE_MONTHLY_DATE ||
  5290.               selectedReminders[0].recurrence.type == REMINDER_RECURRENCE_MONTHLY_DAY ||
  5291.               selectedReminders[0].recurrence.type == REMINDER_RECURRENCE_WEEKLY ||
  5292.               selectedReminders[0].recurrence.type == REMINDER_RECURRENCE_DAILY) ) {
  5293.         removeReminder(selectedReminders[0], true);            
  5294.     }
  5295.     else {
  5296.         var deleteDescription  = null;
  5297.         var reminderTitle = null;
  5298.         if ( selectedReminders.length == 1 ) {
  5299.             deleteDescription = g_reminderFoxBundle.getString("rf.add.deleteReminder.description") + "\n";
  5300.             reminderTitle = g_reminderFoxBundle.getString("rf.add.deleteReminder.title");
  5301.         }
  5302.         else {
  5303.             deleteDescription = g_reminderFoxBundle.getString("rf.add.deleteReminders.description") + "\n";
  5304.             reminderTitle = g_reminderFoxBundle.getString("rf.add.deleteReminders.title");
  5305.         }
  5306.         
  5307.         
  5308.         var reminderDateLabelArray = new Array();  // store the date label and delete date before we start deleting the reminders, as then the selected indices get shifted
  5309.         var reminderDeleteDateArray = new Array();
  5310.         for ( var i = 0; i < selectedReminders.length; i++ ) {        
  5311.             var currentReminder = selectedReminders[i];
  5312.             var deleteDate = getInstanceDateOfLastSelected( currentReminder ); 
  5313.             var dateLabel = reminderFox_getDateVariableString( currentReminder, deleteDate );
  5314.             reminderDateLabelArray[currentReminder.id]= dateLabel;                        
  5315.             reminderDeleteDateArray[currentReminder.id]= deleteDate;
  5316.             var descLabel = currentReminder.summary;
  5317.             deleteDescription += dateLabel + ": " + descLabel + "\n";
  5318.         }
  5319.             
  5320.         var nsIPromptService = Components.interfaces.nsIPromptService;
  5321.         var nsPrompt_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
  5322.         var gPromptService = Components.classes[nsPrompt_CONTRACTID].getService(nsIPromptService);
  5323.         if (gPromptService.confirm(window,
  5324.             reminderTitle,  
  5325.             deleteDescription)) {
  5326.             
  5327.             for ( var i = 0; i < selectedReminders.length; i++ ) {        
  5328.                 var currentReminder = selectedReminders[i];                
  5329.                  removeReminder(currentReminder, true, reminderDeleteDateArray[currentReminder.id], reminderDateLabelArray[currentReminder.id]);
  5330.             }        
  5331.          }
  5332.     }
  5333.     
  5334.     refreshCalendar(false, true);            
  5335.     modifiedReminders();
  5336. }
  5337.  
  5338.  
  5339.  
  5340.  
  5341. function userMoveReminderToTodo(eventTarget) {
  5342.     var targetTodoListName =  eventTarget.getAttribute( "label" );
  5343.     
  5344.     // if moving to ToDo's, use special "ToDo's" id (as label could be another language)
  5345.     var tabList = document.getElementById("tabList");    
  5346.     var tablistItem = tabList.childNodes[1];      // get second tab -- "ToDo's"
  5347.     var tabLabel = tablistItem.getAttribute("label");        
  5348.     if ( tabLabel == targetTodoListName) {
  5349.         targetTodoListName = REMINDER_FOX_DEFAULT_TODOS_CATEGORY;
  5350.     }
  5351.     
  5352.     var reminderItem = tabList.childNodes[0];      // get second tab -- "ToDo's"
  5353.     var remindertabLabel = reminderItem.getAttribute("label");        
  5354.     if ( remindertabLabel == targetTodoListName) {
  5355.         //targetTodoListName = REMINDER_FOX_DEFAULT_TODOS_CATEGORY;
  5356.         // dealing with reminders...
  5357.         
  5358.         var selectedReminders = getAllSelectedReminders();
  5359.         for ( var i = 0; i < selectedReminders.length; i++ ) {        
  5360.             var currentReminder = selectedReminders[i];
  5361.         //    var newTodo = reminderFox_convertReminderToTodo( currentReminder );
  5362.             var newReminder = reminderFox_cloneReminderFoxEvent(currentReminder);
  5363.             // remove from reminders
  5364.             removeReminder(currentReminder);
  5365.                             
  5366.             var reminders = reminderFox_getReminderEvents();                
  5367.             var sortedIndex = reminderFox_getSortedIndexOfNewReminder( reminders, newReminder, false );
  5368.             reminderFox_insertIntoArray( reminders, newReminder, sortedIndex );
  5369.     
  5370.             //createListItem(newReminder);  // update UI list
  5371.  
  5372.         }    
  5373.         // if todo list is selected (has child nodes, need to add a list item to it)
  5374.         reminderFoxTabDirtied = true;
  5375.         
  5376.         refreshCalendar();
  5377.     
  5378.         modifiedReminders();                        
  5379.         
  5380.         return;
  5381.         
  5382.         
  5383.     }
  5384.     
  5385.     
  5386.     var todosArr =    reminderFox_getReminderTodos();
  5387.     var todos = todosArr[targetTodoListName];
  5388.     if ( todos == null ) {
  5389.         todos = new Array();
  5390.         todosArr[targetTodoListName] = todos;
  5391.     }        
  5392.     
  5393.     var selectedReminders = getAllSelectedReminders();
  5394.     for ( var i = 0; i < selectedReminders.length; i++ ) {        
  5395.         var currentReminder = selectedReminders[i];
  5396.         var newTodo = reminderFox_convertReminderToTodo( currentReminder );
  5397.         
  5398.         // remove from reminders
  5399.         removeReminder(currentReminder);
  5400.                         
  5401.         var sortedIndex = reminderFox_getSortedIndexOfNewTodo(todos, newTodo );
  5402.         reminderFox_insertIntoArray( todos, newTodo, sortedIndex );                    
  5403.     }    
  5404.     // if todo list is selected (has child nodes, need to add a list item to it)
  5405.     reminderFoxTabDirtied = true;
  5406.     
  5407.     refreshCalendar();
  5408.  
  5409.     modifiedReminders();                        
  5410.  
  5411. }
  5412.  
  5413. function userDeleteTodo() {
  5414.     var deleteDescription = g_reminderFoxBundle.getString("rf.add.deleteToDo.description") + "\n  ";
  5415.  
  5416.     var selectedTodos = getAllSelectedTodos();
  5417.     for ( var i = 0; i < selectedTodos.length; i++ ) {        
  5418.         var currentTodo = selectedTodos[i];
  5419.         var dateLabel = "";
  5420.         if ( currentTodo.date != null ) {
  5421.              dateLabel = reminderFox_getDateVariableString( currentTodo, currentTodo.date ) + ": ";
  5422.         }        
  5423.         var descLabel = currentTodo.summary;
  5424.         deleteDescription += dateLabel  + descLabel + "\n";
  5425.     }
  5426.     
  5427.     var nsIPromptService = Components.interfaces.nsIPromptService;
  5428.     var nsPrompt_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
  5429.     var gPromptService = Components.classes[nsPrompt_CONTRACTID].getService(nsIPromptService);
  5430.     if (gPromptService.confirm(window,
  5431.             g_reminderFoxBundle.getString("rf.add.deleteToDo.title"),
  5432.             deleteDescription  )) {
  5433.  
  5434.         var selectedTodos = getAllSelectedTodos();
  5435.         for ( var i = 0; i < selectedTodos.length; i++ ) {        
  5436.             var currentTodo = selectedTodos[i];
  5437.              removeTodo(currentTodo);
  5438.         }
  5439.           modifiedReminders();
  5440.      }
  5441.      refreshCalendar(true, false);
  5442. }
  5443.  
  5444. function getTreeItemIndexForTodo( todo ) {
  5445.     var treeChildren = document.getElementById("todoTreechildren");
  5446.     var treeitems = treeChildren.childNodes;
  5447.     for (var i=treeitems.length - 1; i >= 0; i--) {
  5448.         var item = treeitems[i];
  5449.         var row = item.childNodes[0];
  5450.         var reminderRefId = row.getAttribute(REMINDER_ID_REF);    
  5451.         if ( reminderRefId == todo.id ) {            
  5452.             //return item;
  5453.             return i;
  5454.         }
  5455.     }
  5456.     return -1;
  5457. }
  5458.  
  5459.  
  5460. function moveTodoUp() {
  5461.     if ( !isFirstTodoSelected( ) ) {
  5462.         var oldIndices = getAllSelectedTodoIndices();
  5463.         var todos = getCurrentTodoList();
  5464.         var treeChildren = document.getElementById("todoTreechildren");
  5465.         for ( var k = 0; k < oldIndices.length; k++ ) {
  5466.             var index = oldIndices[k];        
  5467.             var selectedTreeItem = treeChildren.childNodes[index];
  5468.             var currentTodoRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  5469.             var currentTodo =  reminderFox_getTodosById( currentTodoRefId,     todos);
  5470.         
  5471.             if ( index > 0 ) {
  5472.                 var previousIndex = index -1;                
  5473.                 var previousselectedTreeItem = treeChildren.childNodes[previousIndex];
  5474.                 var todoRefId = previousselectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  5475.  
  5476.                 // get current index inside of todo array in memory
  5477.                 var i;
  5478.                 var found = false;
  5479.                 for (  i = 0; i < todos.length; i++ ) {
  5480.                     if ( todos[i].id == todoRefId ) {
  5481.                         found = true;
  5482.                         break;
  5483.                     }
  5484.                 }
  5485.                 
  5486.                 if ( found && i >= 0 ) { 
  5487.                     //var newIndex = getPreviousTodoIndex(todos, i );  // insert before old position
  5488.                     var newIndex = i;
  5489.                     var newTodo =    reminderFox_cloneReminderFoxTodo( currentTodo );
  5490.                     var selectedTreeItemIndex = getTreeItemIndexForTodo( newTodo );
  5491.                     removeTodo(currentTodo);
  5492.                         
  5493.                     reminderFox_insertIntoArray( todos, newTodo, newIndex );        
  5494.                     
  5495.                     var newListIndex = selectedTreeItemIndex - 1;
  5496.                     createTodoListItemAtIndex(newTodo,newListIndex );                        
  5497.                 }        
  5498.             }
  5499.         }
  5500.         
  5501.         // update the selected items
  5502.         var treeSelection = document.getElementById("todoTree").view.selection        
  5503.         for ( var k = 0; k < oldIndices.length; k++ ) {
  5504.             var index = oldIndices[k];        
  5505.             treeSelection.rangedSelect((index-1), (index-1), true);
  5506.         }
  5507.         
  5508.         modifiedReminders();
  5509.     }
  5510.     
  5511. }
  5512.  
  5513.  
  5514.  
  5515. function getAllSelectedTodoIndices() {
  5516.     var treeChildren = document.getElementById("todoTreechildren");
  5517.     var indices = new Array();
  5518.     
  5519.     var start = new Object();
  5520.     var end = new Object();
  5521.     var numRanges =  document.getElementById("todoTree").view.selection.getRangeCount();
  5522.     
  5523.     for (var t = 0; t < numRanges; t++){
  5524.       document.getElementById("todoTree").view.selection.getRangeAt(t,start,end);
  5525.       for (var v = start.value; v <= end.value; v++){
  5526.             indices[indices.length] = v;
  5527.       }
  5528.     }
  5529.  
  5530.     return indices;
  5531. }
  5532.  
  5533.  
  5534. function getAllSelectedReminderIndices() {
  5535.     var treeChildren = document.getElementById("treechildren");
  5536.     var indices = new Array();
  5537.     
  5538.     var start = new Object();
  5539.     var end = new Object();
  5540.     var numRanges =  document.getElementById("reminderTree").view.selection.getRangeCount();
  5541.     
  5542.     for (var t = 0; t < numRanges; t++){
  5543.       document.getElementById("reminderTree").view.selection.getRangeAt(t,start,end);
  5544.       for (var v = start.value; v <= end.value; v++){
  5545.             indices[indices.length] = v;
  5546.       }
  5547.     }
  5548.  
  5549.     return indices;
  5550. }
  5551.  
  5552.  
  5553. function getNextTodoIndex(todos, lastIndex ) { 
  5554.     if ( !HIDE_COMPLETED_ITEMS ) {
  5555.         return lastIndex + 1;
  5556.     }
  5557.  
  5558.     // bypass all completed todos
  5559.     var i;
  5560.     for (  i = lastIndex + 1; i < todos.length; i++ ) {    
  5561.         if ( todos[i].completedDate == null ) {
  5562.             break;
  5563.             
  5564.         }        
  5565.     }
  5566.     return i;    
  5567. }
  5568.  
  5569. function getPreviousTodoIndex(todos, lastIndex ) { 
  5570.     if ( !HIDE_COMPLETED_ITEMS ) {
  5571.         return lastIndex - 1;
  5572.     }
  5573.     
  5574.     // bypass all completed todos
  5575.     var i;
  5576.     for (  i = lastIndex -1; i >= 0; i-- ) {
  5577.         if ( todos[i].completedDate == null ) {
  5578.             break;
  5579.         }        
  5580.     }
  5581.     
  5582.     return i;    
  5583. }
  5584.  
  5585.     
  5586.  
  5587.  
  5588. function moveTodoDown() {        
  5589.     if ( !isLastTodoSelected( ) ) {
  5590.         var oldIndices = getAllSelectedTodoIndices();
  5591.         var todos = getCurrentTodoList();
  5592.         var treeChildren = document.getElementById("todoTreechildren");
  5593.         for ( var k = oldIndices.length -1; k >= 0; k-- ) {
  5594.             var index = oldIndices[k];        
  5595.             var selectedTreeItem = treeChildren.childNodes[index];
  5596.             var currentTodoRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  5597.             var currentTodo =  reminderFox_getTodosById( currentTodoRefId,     todos);
  5598.  
  5599.             var nextIndex = index +1;
  5600.                     
  5601.             var nextselectedTreeItem = treeChildren.childNodes[nextIndex];
  5602.             var todoRefId = nextselectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  5603.             
  5604.             // get current index inside of todo array in memory
  5605.             var i;
  5606.             var found = false;
  5607.             for (  i = 0; i < todos.length; i++ ) {
  5608.                 if ( todos[i].id == currentTodo.id ) {
  5609.                     found = true;
  5610.                     break;
  5611.                 }
  5612.             }
  5613.                         
  5614.             if ( found ) {             
  5615.                 //var newIndex = getNextTodoIndex(todos, i);  // insert after old position (take into account some todos may be hidden as complete)  // actually want index of next VISIBLE todo (use list todos, not memory todos?)
  5616.                 var newIndex = i + 1;  // insert current selected item into the next index location (thus moving it down in the list)
  5617.                 var newTodo =    reminderFox_cloneReminderFoxTodo( currentTodo );
  5618.                 var selectedTreeItemIndex = getTreeItemIndexForTodo( newTodo );            
  5619.                 
  5620.                 removeTodo(currentTodo);
  5621.                                 
  5622.                 reminderFox_insertIntoArray( todos, newTodo, newIndex );                            
  5623.     
  5624.                 var newListIndex = selectedTreeItemIndex + 1;
  5625.                 createTodoListItemAtIndex(newTodo,newListIndex );
  5626.             }
  5627.         }
  5628.     
  5629.         var treeSelection = document.getElementById("todoTree").view.selection        
  5630.         for ( var k = 0; k < oldIndices.length; k++ ) {
  5631.             var index = oldIndices[k];        
  5632.             treeSelection.rangedSelect((index+1), (index+1), true);
  5633.         }
  5634.         
  5635.         modifiedReminders();
  5636.     }
  5637. }
  5638.  
  5639.  
  5640. function toggleTodoImportantFlag() {
  5641.     var selectedTodos = getAllSelectedTodos();
  5642.  
  5643.     for ( var i = 0; i < selectedTodos.length; i++ ) {        
  5644.         var currentTodo = selectedTodos[i];
  5645.         if ( currentTodo.priority == REMINDER_PRIORITY_NORMAL) { 
  5646.             currentTodo.priority = REMINDER_PRIORITY_IMPORTANT;
  5647.         }
  5648.         else {
  5649.             currentTodo.priority = REMINDER_PRIORITY_NORMAL;
  5650.         }
  5651.         
  5652.         var modified = updateTodoInList( currentTodo );
  5653.     }
  5654.     modifiedReminders();
  5655.     refreshCalendar(true, true);
  5656. }
  5657.  
  5658. function getReminderForSelectedItem() {
  5659.     var selectedTreeItemIndex = document.getElementById("reminderTree").currentIndex;
  5660.     if ( selectedTreeItemIndex != -1 ) {
  5661.         var treeChildren = document.getElementById("treechildren");
  5662.         var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  5663.         var reminderRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  5664.         return reminderFox_getRemindersById( reminderRefId,getCurrentReminderList() );
  5665.     }
  5666.     else {
  5667.         return null;
  5668.     }
  5669. }
  5670.  
  5671. function selectReminderById( reminderID) {
  5672.     // make sure reminder list is selected
  5673.     var tabList = document.getElementById("tabList");    
  5674.     var tablistItem = tabList.childNodes[0];
  5675.     if ( tabList.selectedItem != tablistItem ) {
  5676.         tabList.selectedItem = tablistItem;
  5677.     }
  5678.     
  5679.     var treeChildren = document.getElementById("treechildren");
  5680.     var treeitems = treeChildren.childNodes;
  5681.     for (var i=0; i < treeitems.length; i++) {
  5682.         var item = treeitems[i];        
  5683.         var row = item.childNodes[0];
  5684.         var reminderRefId = row.getAttribute(REMINDER_ID_REF);    
  5685.         if ( reminderRefId ==reminderID ) {
  5686.             document.getElementById("reminderTree").currentIndex = i;
  5687.             var treeSelection = document.getElementById("reminderTree").view.selection        
  5688.             treeSelection.select(i);
  5689.             
  5690.             // make sure that newly selected row is shown in scroll pane
  5691.             var value = document.getElementById("treeparent").value;
  5692.               var tree = document.getElementById("reminderTree");            
  5693.             var boxobject = tree.boxObject;
  5694.             boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  5695.  
  5696.             // make sure it shows up at the top if possible
  5697.             var first = boxobject.getFirstVisibleRow();
  5698.             var last = boxobject.getLastVisibleRow();
  5699.             if ( i < first || i > last ) {    
  5700.                 boxobject.scrollToRow(treeitems.length - 1);
  5701.                 boxobject.scrollToRow(treeitems.length - 9);
  5702.             }
  5703.                                 
  5704.             var previousReminderOffset = 3;
  5705.             if ( i < previousReminderOffset ) { 
  5706.                 boxobject.ensureRowIsVisible(i);
  5707.             }
  5708.             else {
  5709.                 boxobject.ensureRowIsVisible(i  - previousReminderOffset);
  5710.             }    
  5711.             break;
  5712.         }
  5713.     }
  5714. }
  5715.  
  5716.  
  5717. function selectTodoById( todoListName, reminderID) {
  5718.     var tabList = document.getElementById("tabList");    
  5719.     
  5720.     for ( var i = 1; i < tabList.childNodes.length; i++ ) {  // i =1, because we want to skip reminders
  5721.         var tablistItem = tabList.childNodes[i];    
  5722.         var tabLabel = tablistItem.getAttribute("label");
  5723.         if ( tabLabel == todoListName) {
  5724.             tabList.selectedItem = tablistItem;
  5725.             var treeChildren = document.getElementById("todoTreechildren");
  5726.             var treeitems = treeChildren.childNodes;
  5727.             for (var i=0; i < treeitems.length; i++) {
  5728.                 var item = treeitems[i];        
  5729.                 var row = item.childNodes[0];
  5730.                 var reminderRefId = row.getAttribute(REMINDER_ID_REF);    
  5731.                 if ( reminderRefId ==reminderID ) {
  5732.                     document.getElementById("todoTree").currentIndex = i;
  5733.                     var treeSelection = document.getElementById("todoTree").view.selection        
  5734.                     treeSelection.select(i);
  5735.                     
  5736.                     // make sure that newly selected row is shown in scroll pane
  5737.                     var value = document.getElementById("treeparent").value;
  5738.                       var tree = document.getElementById("todoTree");            
  5739.                     var boxobject = tree.boxObject;
  5740.                     boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
  5741.         
  5742.                     // make sure it shows up at the top if possible
  5743.                     var first = boxobject.getFirstVisibleRow();
  5744.                     var last = boxobject.getLastVisibleRow();
  5745.                     if ( i < first || i > last ) {    
  5746.                         boxobject.scrollToRow(treeitems.length - 1);
  5747.                         boxobject.scrollToRow(treeitems.length - 9);
  5748.                     }
  5749.                                         
  5750.                     var previousReminderOffset = 3;
  5751.                     if ( i < previousReminderOffset ) { 
  5752.                         boxobject.ensureRowIsVisible(i);
  5753.                     }
  5754.                     else {
  5755.                         boxobject.ensureRowIsVisible(i  - previousReminderOffset);
  5756.                     }    
  5757.                     break;
  5758.                 }
  5759.             }
  5760.             break;
  5761.             
  5762.         }
  5763.     }        
  5764.     
  5765.     
  5766.  
  5767. }
  5768.  
  5769.  
  5770. function getTodoForSelectedItem() {
  5771.     var selectedTreeItemIndex = document.getElementById("todoTree").currentIndex;
  5772.     if ( selectedTreeItemIndex != -1 ) {
  5773.         var treeChildren = document.getElementById("todoTreechildren");
  5774.         var selectedTreeItem = treeChildren.childNodes[selectedTreeItemIndex];
  5775.         if ( selectedTreeItem != null ) {
  5776.             var todoRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  5777.             return reminderFox_getTodosById( todoRefId,     getCurrentTodoList());
  5778.         }
  5779.     }
  5780.     return null;
  5781. }
  5782.  
  5783.  
  5784. function getAllSelectedReminders() {
  5785.     var selectedReminders = new Array();
  5786.     var treeChildren = document.getElementById("treechildren");
  5787.     var selectedIDsHash = {};
  5788.     
  5789.     var start = new Object();
  5790.     var end = new Object();
  5791.     var numRanges =  document.getElementById("reminderTree").view.selection.getRangeCount();
  5792.     
  5793.     for (var t = 0; t < numRanges; t++){
  5794.       document.getElementById("reminderTree").view.selection.getRangeAt(t,start,end);
  5795.       for (var v = start.value; v <= end.value; v++){
  5796.             var selectedTreeItem = treeChildren.childNodes[v];
  5797.             var reminderRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  5798.             selectedIDsHash[reminderRefId]= 0;
  5799.       }
  5800.     }
  5801.     
  5802.     // now we have all the unique IDs in a hash (in case the user selected multiple instances of the same reminder)
  5803.     // so we go through and get all of those unique reminders
  5804.     for ( var n in selectedIDsHash ) {
  5805.         var reminderRefId = n;
  5806.         var reminder = reminderFox_getRemindersById( reminderRefId, getCurrentReminderList() );    
  5807.         selectedReminders[selectedReminders.length] = reminder;
  5808.     }    
  5809.     
  5810.     return selectedReminders;
  5811. }
  5812.  
  5813. function isFirstTodoSelected() {
  5814.     var start = new Object();
  5815.     var end = new Object();
  5816.     var numRanges =  document.getElementById("todoTree").view.selection.getRangeCount();
  5817.     for (var t = 0; t < numRanges; t++){
  5818.       document.getElementById("todoTree").view.selection.getRangeAt(t,start,end);
  5819.       for (var v = start.value; v <= end.value; v++){
  5820.             if ( v == 0 ) {
  5821.                 return true;
  5822.             }
  5823.       }
  5824.     }
  5825.     return false;
  5826. }
  5827.  
  5828. function isLastTodoSelected() {
  5829.     var treeChildren = document.getElementById("todoTreechildren");
  5830.     var treeitems = treeChildren.childNodes;
  5831.     var treeItemsLastIndex = treeitems.length - 1;
  5832.         
  5833.     var start = new Object();
  5834.     var end = new Object();
  5835.     var numRanges =  document.getElementById("todoTree").view.selection.getRangeCount();
  5836.     
  5837.     for (var t = 0; t < numRanges; t++){
  5838.       document.getElementById("todoTree").view.selection.getRangeAt(t,start,end);
  5839.       for (var v = start.value; v <= end.value; v++){
  5840.             if ( v == treeItemsLastIndex ) {
  5841.                 return true;
  5842.             }
  5843.       }
  5844.     }
  5845.     return false;
  5846. }
  5847.  
  5848. function getAllSelectedTodos() {
  5849.     var selectedTodos = new Array();
  5850.     var treeChildren = document.getElementById("todoTreechildren");
  5851.     var selectedIDsHash = {};
  5852.     
  5853.     var start = new Object();
  5854.     var end = new Object();
  5855.     var numRanges =  document.getElementById("todoTree").view.selection.getRangeCount();
  5856.     
  5857.     for (var t = 0; t < numRanges; t++){
  5858.       document.getElementById("todoTree").view.selection.getRangeAt(t,start,end);
  5859.       for (var v = start.value; v <= end.value; v++){
  5860.             var selectedTreeItem = treeChildren.childNodes[v];
  5861.             var reminderRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  5862.             selectedIDsHash[reminderRefId]= 0;
  5863.       }
  5864.     }
  5865.     
  5866.     // now we have all the unique IDs in a hash (in case the user selected multiple instances of the same reminder)
  5867.     // so we go through and get all of those unique reminders
  5868.     for ( var n in selectedIDsHash ) {
  5869.         var reminderRefId = n;
  5870.         var todo = reminderFox_getTodosById( reminderRefId,  getCurrentTodoList() );        
  5871.         selectedTodos[selectedTodos.length] = todo;
  5872.     }    
  5873.     
  5874.     return selectedTodos;
  5875. }
  5876.  
  5877.  
  5878.  
  5879.  
  5880. function toggleImportantFlag() {
  5881.     var selectedReminders = getAllSelectedReminders();
  5882.     for ( var i = 0; i < selectedReminders.length; i++ ) {        
  5883.         var currentReminder = selectedReminders[i];
  5884.         if ( currentReminder.priority == REMINDER_PRIORITY_NORMAL) { 
  5885.             currentReminder.priority = REMINDER_PRIORITY_IMPORTANT;
  5886.         }
  5887.         else {
  5888.             currentReminder.priority = REMINDER_PRIORITY_NORMAL;
  5889.         }
  5890.         var modified = updateReminderInList( currentReminder );
  5891.     }
  5892.     refreshCalendar(true, true);
  5893. }
  5894.  
  5895. function updateReminderInList( reminder) {
  5896.     var modified = true;
  5897.     var treeChildren = document.getElementById("treechildren");
  5898.     var todaysDate= new Date();
  5899.     var treeitems = treeChildren.childNodes;
  5900.     
  5901.     var year = oeDatePicker.gSelectedDate.getFullYear();
  5902.     if ( year == null ) {
  5903.         year = new Date().getFullYear();
  5904.     }
  5905.     var reminderInstanceDate;
  5906.     for (var i=0; i < treeitems.length; i++) {
  5907.         var item = treeitems[i];        
  5908.         var row = item.childNodes[0];
  5909.         var reminderRefId = row.getAttribute(REMINDER_ID_REF);    
  5910.         if ( reminderRefId == reminder.id ) {
  5911.             // check if reminder.complete and then reminder.date compared to today's date - first one
  5912.             // >= today, mark it as complete.  No others... 
  5913.             //if ( reminder.completedDate != null  ) {   
  5914.                 var reminderDateTime = row.getAttribute(REMINDER_DATE_REF);    
  5915.                 var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  5916.             //}
  5917.             updateReminder(  reminder, item, reminderInstanceDate );
  5918.         }
  5919.     }
  5920.     reminder.lastModified = reminderFox_getDateAsString(todaysDate );
  5921.  
  5922.     if ( modified ) {
  5923.         modifiedReminders();    
  5924.     }
  5925.     return modified;
  5926. }
  5927.  
  5928. function getTreeItemForReminder( reminder ) {
  5929.     var treeChildren = document.getElementById("treechildren");
  5930.     var treeitems = treeChildren.childNodes;
  5931.     for (var i=treeitems.length - 1; i >= 0; i--) {
  5932.         var item = treeitems[i];
  5933.         var row = item.childNodes[0];
  5934.         var reminderRefId = row.getAttribute(REMINDER_ID_REF);    
  5935.         if ( reminderRefId == reminder.id ) {            
  5936.             return item;
  5937.         }
  5938.     }
  5939.     return null;
  5940. }
  5941.  
  5942. function updateReminder( reminder, selectedTreeItem, reminderInstanceDate) {
  5943.     var modified = true;
  5944.  
  5945.     if ( selectedTreeItem == null ) {
  5946.         selectedTreeItem = getTreeItemForReminder( reminder );
  5947.     }
  5948.  
  5949.     var dateNode = selectedTreeItem.childNodes[0].childNodes[0];
  5950.     var descriptionNode = selectedTreeItem.childNodes[0].childNodes[1];
  5951.     var timeNode = selectedTreeItem.childNodes[0].childNodes[2];            
  5952.     var completedDateNode = selectedTreeItem.childNodes[0].childNodes[3];              
  5953.     var repeatNode = selectedTreeItem.childNodes[0].childNodes[4];            
  5954.     var completeNode = selectedTreeItem.childNodes[0].childNodes[5];           
  5955.     var remindUntilCompleteNode = selectedTreeItem.childNodes[0].childNodes[6];                     
  5956.     var notesNode = selectedTreeItem.childNodes[0].childNodes[7];                 
  5957.     var alarmNode = selectedTreeItem.childNodes[0].childNodes[8];    
  5958.     var categoryNode = selectedTreeItem.childNodes[0].childNodes[9];    
  5959.     var endDateNode = selectedTreeItem.childNodes[0].childNodes[10];     
  5960.     var mailNode = selectedTreeItem.childNodes[0].childNodes[11];                  
  5961.     
  5962.     // update description
  5963.     
  5964.     var year = oeDatePicker.gSelectedDate.getFullYear();
  5965.     if ( year == null ) {
  5966.         year = new Date().getFullYear();
  5967.     }
  5968.  
  5969.     var todaysDate = new Date();
  5970.     
  5971.     var isToday = reminderFox_compareDates( reminderInstanceDate, todaysDate) == 0 ;
  5972.     var isImportant = reminder.priority == REMINDER_PRIORITY_IMPORTANT;
  5973.     var isCompleted =  reminderFox_isCompletedForDate( reminder, reminderInstanceDate ) ;
  5974.  
  5975.     reminder = reminderFox_processReminderDescription(reminder, year, false);
  5976.     descriptionNode.setAttribute( "label", reminder.summary );
  5977.  
  5978.     setTextProperties( isToday, isImportant, isCompleted, dateNode, descriptionNode, timeNode );                
  5979.        
  5980.  
  5981.         if ( reminder.allDayEvent ) {
  5982.             timeNode.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  5983.         }
  5984.         else {
  5985.             var time = reminderFox_getAddTimeString(reminder);
  5986.             if ( time == null ) {
  5987.                 timeNode.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  5988.             }
  5989.             else {
  5990.                 timeNode.setAttribute("label", time);
  5991.             }
  5992.         }       
  5993.         // update once
  5994.         if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) {
  5995.             repeatNode.setAttribute("label", REPEAT_LABEL_YEARLY);
  5996.         }
  5997.         else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) {
  5998.             repeatNode.setAttribute("label", REPEAT_LABEL_YEARLY_DAY);
  5999.         }        
  6000.         else     if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
  6001.             repeatNode.setAttribute("label", REPEAT_LABEL_MONTHLY);
  6002.         }
  6003.         else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {
  6004.             repeatNode.setAttribute("label", REPEAT_LABEL_MONTHLY_DAY);
  6005.         }
  6006.         else    if ( reminder.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {    
  6007.             repeatNode.setAttribute("label", REPEAT_LABEL_WEEKLY);
  6008.         }
  6009.         else    if ( reminder.recurrence.type  == REMINDER_RECURRENCE_DAILY ) {        
  6010.             repeatNode.setAttribute("label", REPEAT_LABEL_DAILY);
  6011.         }            
  6012.         else {        
  6013.             repeatNode.setAttribute("label", REPEAT_LABEL_NONE);
  6014.         }        
  6015.         
  6016.        // update complete
  6017.       var isCompleted = reminderFox_isCompletedForDate( reminder, reminderInstanceDate );
  6018.       if ( isCompleted )  {
  6019.                completeNode.setAttribute("src",REMINDER_FOX_COMPLETED_IMAGE);    
  6020.              
  6021.             if ( useDefaultDate ) {
  6022.                 var monthAsText = reminderFox_getMonthAsText(reminder.completedDate.getMonth());        
  6023.                 completedDateNode.setAttribute("label", monthAsText + " " + reminder.completedDate.getDate());
  6024.             }
  6025.             else {
  6026.                 completedDateNode.setAttribute("label", reminderFox_getDateVariableString( reminder, reminder.completedDate ) );
  6027.             }                  
  6028.         }
  6029.          else {
  6030.                 completeNode.removeAttribute("src");
  6031.                     completedDateNode.removeAttribute("label");
  6032.         }
  6033.         
  6034.         if ( reminder.endDate != null ) {
  6035.             var monthAsText = reminderFox_getMonthAsText(reminder.endDate.getMonth());        
  6036.             if ( useDefaultDate ) {
  6037.                 endDateNode.setAttribute("label", monthAsText + " " + reminder.endDate.getDate());
  6038.             }
  6039.             else {
  6040.                 endDateNode.setAttribute("label", reminderFox_getDateVariableString( reminder, reminder.endDate ) );
  6041.             }    
  6042.         }
  6043.         else {
  6044.             endDateNode.removeAttribute("label");
  6045.         }
  6046.                 
  6047.          // update remind until complete
  6048.          if ( reminder.remindUntilCompleted != REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE ) {
  6049.              setRemindUntilCompleteColumn( reminder, remindUntilCompleteNode );             
  6050.          }
  6051.         else {
  6052.                 remindUntilCompleteNode.removeAttribute("src");
  6053.         }       
  6054.  
  6055.           if ( reminder.notes != null ) {
  6056.                //  notesNode.setAttribute("properties", "notes");
  6057.              notesNode.setAttribute("src", REMINDER_FOX_NOTES_IMAGE);            
  6058.          }              
  6059.         else {
  6060.                 notesNode.removeAttribute("src");
  6061.                 //notesNode.removeAttribute("properties");
  6062.         }            
  6063.         
  6064.         if ( reminder.alarm != null ) {
  6065.             if ( reminder.snoozeTime != null && !isCompleted) { 
  6066.                 alarmNode.setAttribute("src",REMINDER_FOX_ALARM_SNOOZE_IMAGE);        
  6067.             }
  6068.             else {
  6069.                  alarmNode.setAttribute("src",REMINDER_FOX_ALARM_IMAGE);            
  6070.             }                 
  6071.         }
  6072.         else {
  6073.             alarmNode.removeAttribute("src");
  6074.         }                
  6075.         
  6076.         if ( reminder.categories != null ) {
  6077.              categoryNode.setAttribute("label", reminder.categories);
  6078.         }
  6079.         else {
  6080.             categoryNode.removeAttribute("label");                
  6081.         }
  6082.         
  6083.           if ( mailNode != null ) {
  6084.               if ( reminder.messageID != null ) {
  6085.                 mailNode.setAttribute("src", REMINDER_FOX_MAIL_IMAGE);    
  6086.               }                
  6087.             else {
  6088.                 mailNode.removeAttribute("src");
  6089.             }
  6090.           }                            
  6091. }
  6092.   
  6093.   
  6094.  
  6095.   
  6096.   
  6097.   
  6098. function updateTodoInList( todo) {
  6099.     var modified = true;
  6100.     var treeChildren = document.getElementById("todoTreechildren");
  6101.     var treeitems = treeChildren.childNodes;
  6102.     for (var i=0; i < treeitems.length; i++) {
  6103.         var selectedTreeItem = treeitems[i];        
  6104.         var row = selectedTreeItem.childNodes[0];
  6105.         var reminderRefId = row.getAttribute(REMINDER_ID_REF);    
  6106.         if ( reminderRefId == todo.id ) {                        
  6107.             var dateNode = selectedTreeItem.childNodes[0].childNodes[0];
  6108.             var descriptionNode = selectedTreeItem.childNodes[0].childNodes[1];
  6109.             var timeNode = selectedTreeItem.childNodes[0].childNodes[2];
  6110.             var completedDateNode = selectedTreeItem.childNodes[0].childNodes[3];       
  6111.             var completeNode = selectedTreeItem.childNodes[0].childNodes[4];           
  6112.             var showInTooltipNode = selectedTreeItem.childNodes[0].childNodes[5];    
  6113.             var notesNode = selectedTreeItem.childNodes[0].childNodes[6];       
  6114.             var alarmNode = selectedTreeItem.childNodes[0].childNodes[7];
  6115.             var categoryNode = selectedTreeItem.childNodes[0].childNodes[8];       
  6116.             var endDateNode = selectedTreeItem.childNodes[0].childNodes[9];      
  6117.              var mailNode = selectedTreeItem.childNodes[0].childNodes[10];                  
  6118.             
  6119.             if ( todo.date != null ) {
  6120.                 var monthAsText = reminderFox_getMonthAsText(todo.date.getMonth());        
  6121.                 if ( useDefaultDate ) {
  6122.                     dateNode.setAttribute("label", monthAsText + " " + todo.date.getDate());
  6123.                 }
  6124.                 else {
  6125.                     dateNode.setAttribute("label", reminderFox_getDateVariableString( todo, todo.date ) );
  6126.                 }    
  6127.                         
  6128.                 if (  todo.allDayEvent ) {
  6129.                     timeNode.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  6130.                 }
  6131.                 else {
  6132.                     var time = reminderFox_getAddTimeString(todo);
  6133.                     if ( time == null ) {
  6134.                         timeNode.setAttribute("label", REMINDER_FOX_TIME_ALL_DAY_LABEL);
  6135.                     }
  6136.                     else {            
  6137.                         timeNode.setAttribute("label", time);
  6138.                     }
  6139.                 }            
  6140.             }
  6141.             else {
  6142.                 dateNode.removeAttribute( "label" );
  6143.                 timeNode.removeAttribute("label");
  6144.             }
  6145.             
  6146.             if ( todo.endDate != null ) {
  6147.                 var monthAsText = reminderFox_getMonthAsText(todo.endDate.getMonth());        
  6148.                 if ( useDefaultDate ) {
  6149.                     endDateNode.setAttribute("label", monthAsText + " " + todo.endDate.getDate());
  6150.                 }
  6151.                 else {
  6152.                     endDateNode.setAttribute("label", reminderFox_getDateVariableString( todo, todo.endDate ) );
  6153.                 }    
  6154.             }
  6155.             else {
  6156.                 endDateNode.removeAttribute( "label" );
  6157.             }
  6158.             
  6159.             
  6160.             
  6161.             // update description
  6162.              todo = reminderFox_processReminderDescription(todo,  new Date().getFullYear(), true );    
  6163.             descriptionNode.setAttribute( "label", todo.summary );
  6164.             
  6165.              // update importance
  6166.              var isImportant = false;
  6167.              if ( todo.priority == REMINDER_PRIORITY_IMPORTANT) { 
  6168.                  // mark the description as important (red-highlighted)
  6169.                 descriptionNode.setAttribute("properties", "important");
  6170.                 isImportant = true;
  6171.              }
  6172.              else {
  6173.                 descriptionNode.removeAttribute("properties");
  6174.              }
  6175.              
  6176.            // update show in tooltip
  6177.            if ( todo.completedDate != null  ) {
  6178.                 completeNode.setAttribute("src",REMINDER_FOX_COMPLETED_TODO_IMAGE);    
  6179.                 
  6180.                     if ( isImportant ) {
  6181.                      descriptionNode.setAttribute("properties", "imporantCompleteText");         
  6182.                  }
  6183.                  else {
  6184.                      descriptionNode.setAttribute("properties", "completeText");         
  6185.                  }         
  6186.                  
  6187.                  
  6188.                 if ( useDefaultDate ) {
  6189.                     var monthAsText = reminderFox_getMonthAsText(todo.completedDate.getMonth());        
  6190.                     completedDateNode.setAttribute("label", monthAsText + " " + todo.completedDate.getDate());
  6191.                 }
  6192.                 else {
  6193.                     completedDateNode.setAttribute("label", reminderFox_getDateVariableString( todo, todo.completedDate ) );
  6194.                 }               
  6195.                      
  6196.              }
  6197.              else {
  6198.                     if ( isImportant ) {
  6199.                          //descriptionNode.setAttribute("properties", "imporantCompleteText");         
  6200.                                       // mark the date and description as important (red-highlighted)
  6201.                     //dateNode.setAttribute("properties", "important");
  6202.                  }
  6203.                  else {
  6204.                      descriptionNode.removeAttribute( "properties" );  // completed setatus?
  6205.                  }                  
  6206.                 completeNode.removeAttribute("src");
  6207.                 completedDateNode.removeAttribute("label");
  6208.             }         
  6209.            
  6210.            // update show in tooltip   
  6211.            if ( todo.showInTooltip ) {
  6212.                  showInTooltipNode.setAttribute("src", REMINDER_FOX_SHOW_IN_TOOLTIP_IMAGE);         
  6213.              }
  6214.              else {
  6215.                 showInTooltipNode.removeAttribute("src");
  6216.             }    
  6217.         
  6218.            if ( todo.notes != null  ) {
  6219.                  notesNode.setAttribute("src",REMINDER_FOX_NOTES_IMAGE);    
  6220.              }
  6221.              else {
  6222.                 notesNode.removeAttribute("src");
  6223.             }        
  6224.         
  6225.             if ( todo.alarm != null ) {
  6226.                 if ( todo.snoozeTime != null && todo.completedDate == null  ) { 
  6227.                     alarmNode.setAttribute("src",REMINDER_FOX_ALARM_SNOOZE_IMAGE);        
  6228.                 }
  6229.                 else {
  6230.                      alarmNode.setAttribute("src",REMINDER_FOX_ALARM_IMAGE);            
  6231.                 }                 
  6232.              }
  6233.              else {
  6234.                 alarmNode.removeAttribute("src");
  6235.             }        
  6236.             
  6237.             if ( todo.categories != null ) {
  6238.                  categoryNode.setAttribute("label", todo.categories);
  6239.             }
  6240.             else {
  6241.                 categoryNode.removeAttribute("label");                
  6242.             }
  6243.                 
  6244.               if ( mailNode != null ) {
  6245.                   if ( todo.messageID != null ) {
  6246.                     mailNode.setAttribute("src", REMINDER_FOX_MAIL_IMAGE);    
  6247.                   }                
  6248.                 else {
  6249.                     mailNode.removeAttribute("src");
  6250.                 }
  6251.               }
  6252.               break;           
  6253.         }
  6254.     }
  6255.         
  6256.     if ( modified ) {
  6257.         modifiedReminders();    
  6258.     }
  6259.     return modified;
  6260.         
  6261. }
  6262.  
  6263. function refreshCalendar( keepReminderArray, keepTodoArray ) {
  6264.     if ( !keepReminderArray ) { 
  6265.         calendarReminderArray = null;    
  6266.     }
  6267.     if ( !keepTodoArray) {
  6268.         calendarTodoArray = null;
  6269.     }
  6270.     oeDatePicker.redrawDays();
  6271. }
  6272.  
  6273.  
  6274. function toggleTodoShowInTooltip() {
  6275.     var selectedTodos = getAllSelectedTodos();
  6276.     for ( var i = 0; i < selectedTodos.length; i++ ) {        
  6277.         var currentTodo = selectedTodos[i];    
  6278.         currentTodo.showInTooltip = !currentTodo.showInTooltip;
  6279.         var modified = updateTodoInList( currentTodo );
  6280.     }
  6281.     modifiedReminders();
  6282. }
  6283.  
  6284. function toggleRemindUntilCompleted() {
  6285.     var selectedReminders = getAllSelectedReminders();
  6286.     for ( var i = 0; i < selectedReminders.length; i++ ) {        
  6287.         var currentReminder = selectedReminders[i];        
  6288.         var cleanUpReminderInList = false;
  6289.  
  6290. //gW_RecurringEvents 2009-02-27     // NON recurring events are handled here 
  6291.     if (currentReminder.recurrence.type == null) {
  6292.         if ( currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE ) {    
  6293.             var todaysDate = new Date();
  6294.             if (reminderFox_compareDates( currentReminder.date, todaysDate ) == -1) { // -1: date is in the past
  6295.                 currentReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED;
  6296.                 cleanUpReminderInList = true;
  6297.             } else {
  6298.                 currentReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED;
  6299.             }
  6300.         }
  6301.         else if (( currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED ) 
  6302.             ||  ( currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED)) {
  6303.             currentReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE;
  6304.             cleanUpReminderInList = true;
  6305.         }
  6306.     } else {//  recurring events are handled here 
  6307.     
  6308.         if ( currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE ) {
  6309.             currentReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED;
  6310.         }
  6311.         else if ( currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED ) {
  6312.             currentReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE;
  6313.         }
  6314.         else     if ( currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED ) {
  6315.             currentReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE;
  6316.             cleanUpReminderInList = true;
  6317.         }
  6318.     }        
  6319.         var modified = updateReminderInList( currentReminder );
  6320.     
  6321.         modifiedReminders();
  6322.         
  6323.         // if is was marked as RemindUntilCompleted and was showing in the list at a later date, we  need to remove this from the
  6324.         // UI list back to its original location
  6325.         if ( cleanUpReminderInList ) {
  6326.             removeListItemsForReminder(currentReminder);
  6327.             createListItem(currentReminder    );
  6328.         }
  6329.     }
  6330.     
  6331.     refreshCalendar(false, true);
  6332. }
  6333.  
  6334.  
  6335. function toggleMarkAsComplete() {    
  6336.     var selectedReminders = new Array();
  6337.     var treeChildren = document.getElementById("treechildren");
  6338.     var selectedIDsHash = {};
  6339.     
  6340.     var start = new Object();
  6341.     var end = new Object();
  6342.     var numRanges =  document.getElementById("reminderTree").view.selection.getRangeCount();
  6343.     
  6344.     for (var t = 0; t < numRanges; t++){
  6345.       document.getElementById("reminderTree").view.selection.getRangeAt(t,start,end);
  6346.       for (var v = start.value; v <= end.value; v++){
  6347.         var selectedTreeItem = treeChildren.childNodes[v];
  6348.             
  6349.         var reminderRefId = selectedTreeItem.childNodes[0].getAttribute(REMINDER_ID_REF);
  6350.         var currentReminder = reminderFox_getRemindersById( reminderRefId, getCurrentReminderList() );    
  6351.            if ( currentReminder != null ) {
  6352.             var reminderDateTime = selectedTreeItem.childNodes[0].getAttribute(REMINDER_DATE_REF);    
  6353.             var reminderInstanceDate = new Date(parseInt(reminderDateTime));        
  6354.             if ( reminderFox_isCompletedForDate( currentReminder, reminderInstanceDate ) )  {
  6355.                 currentReminder.completedDate = null;                                                                                            
  6356.             }
  6357.             else {     
  6358.                  var todaysDate = new Date();
  6359.                   // if it's a one time reminder just use today's date        
  6360.                  if ( currentReminder.recurrence.type  == REMINDER_RECURRENCE_ONETIME ) { 
  6361.                       currentReminder.completedDate = todaysDate;                     
  6362.                  }
  6363.                  else { 
  6364.                      var compare = reminderFox_compareDates( reminderInstanceDate, todaysDate );                    
  6365.                      if ( compare >= 0 ) {  // if reminder is today or in the future, just use that instance date
  6366.                          currentReminder.completedDate = reminderInstanceDate;    
  6367.                      }
  6368.                      else {     
  6369.                             // if we mark a repeating guy as complete and the next instance is in the future, then use today's date as the complete
  6370.                             // date, and not the occurrence. 
  6371.                             var currentInstanceDate = new Date( reminderInstanceDate.getFullYear(), reminderInstanceDate.getMonth(), reminderInstanceDate.getDate(), 
  6372.                                 reminderInstanceDate.getHours(), reminderInstanceDate.getMinutes() );
  6373.                             currentInstanceDate.setDate( currentInstanceDate.getDate() + 1);
  6374.                             var nextReminderInstance = reminderFox_getFirstReminderOccurrenceAfterStartDate( currentReminder, currentInstanceDate );                        
  6375.                             var compare = reminderFox_compareDates( nextReminderInstance.date, todaysDate );
  6376.                             if ( compare == 1 ) { // if today's date is greater than instance, use today
  6377.                                 currentReminder.completedDate = todaysDate;                        
  6378.                             }
  6379.                             else {
  6380.                                 // if today's date is less than or equal to the reminder instance's date, then use the reminder's date
  6381.                                 currentReminder.completedDate = reminderInstanceDate;    
  6382.                             }                            
  6383.                      }
  6384.                  }
  6385.                                                  
  6386.                 //gW TAG  2008-12-14    do we really want to delete the TAG with 'COMPLETE' ??
  6387.                 // need to clear Mail label if a message is attached to this reminder
  6388.                 /** ----------
  6389.                 if ( currentReminder.messageID != null ) {        
  6390.                     if ( window.arguments != null ) {                
  6391.                         var clearMailLabelCallback = window.arguments[1].clearMailLabelCallback;
  6392.                         if ( clearMailLabelCallback != null ) {                
  6393.                             clearMailLabelCallback(  currentReminder.messageID );
  6394.                         }
  6395.                     }
  6396.                 }    ----------- **/
  6397.  
  6398.                 // if reminder is marked as Remind Until Complete, clear it (if one-time, clear the RUC completely;
  6399.                 // if a repeating reminder, simply change back to RUC-marked)  and update the reminder
  6400.                 //  in the list (as the current reminder instance may be removed)
  6401.                 if (  currentReminder.recurrence.type  == REMINDER_RECURRENCE_ONETIME && 
  6402.                     ( currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED ||
  6403.                       currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED )  ) {
  6404.                      toggleRemindUntilCompleted(); 
  6405.                      modifiedReminders();
  6406.                      return;      
  6407.                 }    
  6408.                 else if ( currentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED ) {
  6409.                     currentReminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED;
  6410.                     var modified = updateReminderInList( currentReminder );
  6411.                     modifiedReminders();
  6412.                     
  6413.                     // if is was marked as RemindUntilCompleted and was showing in the list at a later date, we  need to remove this from the
  6414.                     // UI list back to its original location
  6415.                     removeListItemsForReminder(currentReminder);
  6416.                     createListItem(currentReminder    );
  6417.                     return;
  6418.                 }        
  6419.             }                    
  6420.     
  6421.             var modified = updateReminderInList( currentReminder );                    
  6422.             sortReminderIfNeccessary( currentReminder.id);
  6423.         }            
  6424.       }
  6425.     }    
  6426.     
  6427.     refreshCalendar(false, true);
  6428.     modifiedReminders();
  6429.     
  6430.     
  6431. }
  6432.  
  6433. function toggleTodoMarkAsComplete() {
  6434.     var selectedTodos = getAllSelectedTodos();
  6435.     for ( var i = 0; i < selectedTodos.length; i++ ) {        
  6436.         var currentTodo = selectedTodos[i];
  6437.             if ( currentTodo.completedDate != null ) { 
  6438.                 currentTodo.completedDate = null;
  6439.             }
  6440.             else {
  6441.                 currentTodo.completedDate = new Date();;
  6442.             }
  6443.             var modified = updateTodoInList( currentTodo );
  6444.             
  6445.             sortTodoIfNeccessary( currentTodo.id);
  6446.     }
  6447.     refreshCalendar(true, false);
  6448.     modifiedReminders();
  6449. }
  6450.  
  6451. function revertActions() {
  6452.     // I don't know how to refresh Reminders and Todos
  6453.     var revertReminders = true;
  6454.     var revertTodos = true;
  6455.  
  6456.     reminderFox_clearRemindersAndTodos();
  6457.     removeAllListItems(revertReminders, revertTodos);
  6458.     calendarReminderArray = null;  // null out in case reminder columns are sorted
  6459.     calendarTodoArray = null;
  6460.     fillList(revertReminders, revertTodos);
  6461.     refreshCalendar();
  6462.  
  6463.     // grey out the rever buttons
  6464.     var revertButton= document.getElementById("revertbutton");
  6465.     revertButton.setAttribute( "disabled", true );
  6466.     
  6467.     var revertButtonTodos= document.getElementById("revertbuttonTodos");
  6468.     revertButtonTodos.setAttribute( "disabled", true );
  6469.     
  6470.     g_modified = false;
  6471. }
  6472.  
  6473. function reminderFox_doFocusQuickSearch() {
  6474.     var desc = document.getElementById("rmSearchText");
  6475.     desc.focus();
  6476. }
  6477.  
  6478. function refillLists() {
  6479.         rmFx_View.LoadCurrentPref();
  6480.     var revertReminders;
  6481.     var revertTodos;
  6482.     
  6483.     if (isReminderTabSelected() ) {
  6484.         revertReminders = true;
  6485.         revertTodos = false;
  6486.     }
  6487.     else {
  6488.         revertReminders = false;
  6489.         revertTodos = true;        
  6490.     }
  6491.  
  6492.     removeAllListItems(revertReminders, revertTodos);
  6493.  
  6494.     fillList(revertReminders, revertTodos);
  6495.     refreshCalendar();
  6496. }
  6497.  
  6498.  
  6499.  
  6500.  
  6501.  function sortcolumn(column) { 
  6502.      var name  = column.getAttribute("id");
  6503.      
  6504.      // get current tab name....    
  6505.     var tabList = document.getElementById("tabList");    
  6506.     var tab =    tabList.selectedItem;
  6507.     var tabName = tab.getAttribute( "label");
  6508.     // get hashmap - check for tabname    
  6509.     var sortInfo = listSortMap[tabName];
  6510.     if ( sortInfo == null ) {
  6511.         // if not there -= then set this tabname-->{column, 0} (ascending)
  6512.         listSortMap[tabName] = { sortColumn: name, sortDirection:  REMINDER_FOX_SORT_DIRECTION_ASCENDING };
  6513.     }
  6514.     else {
  6515.         if ( sortInfo.sortColumn == name ) {    
  6516.             // same column -- increase sortDir
  6517.             if ( sortInfo.sortDirection == REMINDER_FOX_SORT_DIRECTION_ASCENDING ) {
  6518.                 listSortMap[tabName] = { sortColumn: name, sortDirection:  REMINDER_FOX_SORT_DIRECTION_DESCENDING};
  6519.             }
  6520.             else {
  6521.                 //  if desc--> then increase and REMOVE entry
  6522.                 listSortMap[tabName] = null;
  6523.             }
  6524.         }
  6525.         else {
  6526.             // new column
  6527.             listSortMap[tabName] = { sortColumn: name, sortDirection:  REMINDER_FOX_SORT_DIRECTION_ASCENDING };
  6528.         }
  6529.     }
  6530.  
  6531.     if ( isReminderTabSelected() ) {
  6532.          removeAllListItems( true, false );
  6533.         fillList( true, false);
  6534.     }
  6535.     else {
  6536.         removeAllListItems( false, true );
  6537.         fillList( false, true );
  6538.     }
  6539.     
  6540.     modifiedReminders();
  6541.  }
  6542.  
  6543.  
  6544.  function isTabSorted() {
  6545.      var tabList = document.getElementById("tabList");    
  6546.     var tab =    tabList.selectedItem;
  6547.     var tabName = tab.getAttribute( "label");
  6548.     // get hashmap - check for tabname    
  6549.     var sortInfo = listSortMap[tabName];
  6550.     if ( sortInfo != null ) {
  6551.         return true;
  6552.     }
  6553.     else {
  6554.         return false;
  6555.     }
  6556.  }
  6557.  
  6558.  function isTodoTabSorted() {
  6559.      var tabList = document.getElementById("tabList");    
  6560.     var tab =    tabList.childNodes[1];
  6561.     var tabName = tab.getAttribute( "label");
  6562.     
  6563.     // get hashmap - check for tabname    
  6564.     var sortInfo = listSortMap[tabName];
  6565.     if ( sortInfo != null ) {
  6566.         return true;
  6567.     }
  6568.     else {
  6569.         return false;
  6570.     }
  6571.  }
  6572.  
  6573.  function fillListSortTodos() {
  6574.      var tabList = document.getElementById("tabList");    
  6575.     var tab =    tabList.selectedItem;
  6576.     var tabName = tab.getAttribute( "label");
  6577.      
  6578.      clearAllSortColumns(); 
  6579.      if (  listSortMap[tabName].sortDirection == REMINDER_FOX_SORT_DIRECTION_ASCENDING) {
  6580.          var column = document.getElementById(listSortMap[tabName].sortColumn );        
  6581.          column.setAttribute("sortDirection", "ascending");                 
  6582.      }
  6583.      else {         
  6584.          var column = document.getElementById(listSortMap[tabName].sortColumn );        
  6585.          column.setAttribute("sortDirection", "descending");        
  6586.      }     
  6587.      
  6588.      
  6589.      var todos = getCurrentTodoList();
  6590.         
  6591.     var sortedArray;
  6592.     var unsortedArray = new Array();
  6593.     var displayList = document.getElementById("displayTypeTodo");            
  6594.     if ( displayList != null && displayList.selectedIndex > 0 ) {
  6595.         var todaysDate = new Date();
  6596.         var monthArray, dayReminderArray;
  6597.         var monthIndex, dayIndex, reminderIndex;
  6598.         for ( monthIndex = 0; monthIndex < 12; monthIndex++ ) {
  6599.             monthArray = calendarTodoArray[monthIndex];
  6600.             if ( monthArray != null ) {
  6601.                 for ( dayIndex = 0; dayIndex < 31; dayIndex++ ) {
  6602.                     dayReminderArray = monthArray[dayIndex];
  6603.                     if ( dayReminderArray != null ) {
  6604.                         for ( reminderIndex = 0; reminderIndex < dayReminderArray.length; reminderIndex++ ) {
  6605.                             unsortedArray[unsortedArray.length] = dayReminderArray[reminderIndex];
  6606.                         }
  6607.                     }
  6608.                 }
  6609.             }
  6610.         }    
  6611.         
  6612.         sortedArray = new Array( unsortedArray.length );
  6613.         for ( var i = 0; i < unsortedArray.length; i++ ) {
  6614.             sortedArray[i] = unsortedArray[i];
  6615.             sortedArray[i].originalIndex = i;
  6616.         }                 
  6617.     }
  6618.     else {
  6619.         var sortedArray = new Array( todos.length );
  6620.         for ( var i = 0; i < todos.length; i++ ) {
  6621.             sortedArray[i] = todos[i];
  6622.             sortedArray[i].originalIndex = i;
  6623.         }
  6624.     }
  6625.         
  6626.     reminderFox_quick_sort( sortedArray, listSortMap[tabName].sortColumn, listSortMap[tabName].sortDirection );
  6627.             
  6628.     removeAllListItems( false, true );
  6629.     
  6630.     var todaysDate = new Date();
  6631.      for( i = 0; i < sortedArray.length; i++) {
  6632.         createTodoListItem(sortedArray[i], false, todaysDate, false);
  6633.     }
  6634.     highlightTodo();
  6635.         
  6636.        selectNewReminderText();
  6637.  }
  6638.  
  6639.  
  6640.  function fillListSortReminders( ignoreHighlight ) {
  6641.      var tabList = document.getElementById("tabList");    
  6642.     var tab =    tabList.selectedItem;
  6643.     var tabName = tab.getAttribute( "label");
  6644.      
  6645.     clearAllSortColumns();
  6646.      if (  listSortMap[tabName].sortDirection == REMINDER_FOX_SORT_DIRECTION_ASCENDING) {
  6647.          var column = document.getElementById(listSortMap[tabName].sortColumn );        
  6648.          column.setAttribute("sortDirection", "ascending");                 
  6649.      }
  6650.      else {         
  6651.          var column = document.getElementById(listSortMap[tabName].sortColumn );        
  6652.          column.setAttribute("sortDirection", "descending");        
  6653.      }          
  6654.      
  6655.     removeAllListItems( true, false );
  6656.     if ( calendarReminderArray == null ) {
  6657.         createCalendarReminderArray();        
  6658.     }
  6659.     var unsortedArray = new Array();
  6660.     var monthArray, dayReminderArray;
  6661.     var monthIndex, dayIndex, reminderIndex;
  6662.     for ( monthIndex = 0; monthIndex < 12; monthIndex++ ) {
  6663.         monthArray = calendarReminderArray[monthIndex];
  6664.         if ( monthArray != null ) {
  6665.             for ( dayIndex = 0; dayIndex < 31; dayIndex++ ) {
  6666.                 dayReminderArray = monthArray[dayIndex];
  6667.                 if ( dayReminderArray != null ) {
  6668.                     for ( reminderIndex = 0; reminderIndex < dayReminderArray.length; reminderIndex++ ) {
  6669.                         //createListItemSorted(dayReminderArray[reminderIndex]);
  6670.                         unsortedArray[unsortedArray.length] = dayReminderArray[reminderIndex];
  6671.                     }
  6672.                 }
  6673.             }
  6674.         }
  6675.     }
  6676.     
  6677.     
  6678.     var sortedArray = new Array( unsortedArray.length );
  6679.     for ( var i = 0; i < unsortedArray.length; i++ ) {
  6680.         sortedArray[i] = unsortedArray[i];
  6681.         sortedArray[i].originalIndex = i;
  6682.     }        
  6683.     
  6684.     var todaysDate = new Date();
  6685.     reminderFox_quick_sort( sortedArray, listSortMap[tabName].sortColumn, listSortMap[tabName].sortDirection );
  6686.      for( i = 0; i < sortedArray.length; i++) {
  6687.         createListItemSorted(sortedArray[i], todaysDate);
  6688.     }
  6689.     
  6690.     if ( !ignoreHighlight ) {
  6691.         // now that we've added the sorted reminders in the list, let's
  6692.         // select (highlight) today's reminder or the next upcoming reminder
  6693.         highlightClosestUpcomingReminder( new Date());            
  6694.     }
  6695.  }
  6696.  
  6697.  function clearAllSortColumns() {
  6698.      // clear reminder columns
  6699.     if ( isReminderTabSelected() ) {
  6700.         document.getElementById("dateColLabel").removeAttribute("sortDirection");        
  6701.         document.getElementById("descColLabel").removeAttribute("sortDirection");        
  6702.         document.getElementById("timeColLabel").removeAttribute("sortDirection");        
  6703.         document.getElementById("dateCompleted").removeAttribute("sortDirection");        
  6704.         document.getElementById("repeatColLabel").removeAttribute("sortDirection");        
  6705.         document.getElementById("CompleteColLabel").removeAttribute("sortDirection");        
  6706.         document.getElementById("remindUntilCompletedColLabel").removeAttribute("sortDirection");        
  6707.         document.getElementById("notesColLabel").removeAttribute("sortDirection");        
  6708.         document.getElementById("alarmColLabel").removeAttribute("sortDirection");        
  6709.         document.getElementById("mailColLabel").removeAttribute("sortDirection");
  6710.         document.getElementById("catColLabel").removeAttribute("sortDirection");        
  6711.         document.getElementById("endDateColLabel").removeAttribute("sortDirection");                                
  6712.     }
  6713.     else {
  6714.         // clear todo columns
  6715.         document.getElementById("todoDateColLabel").removeAttribute("sortDirection");        
  6716.         document.getElementById("todoDescColLabel").removeAttribute("sortDirection");        
  6717.         document.getElementById("todoDateCompleted").removeAttribute("sortDirection");        
  6718.         document.getElementById("todoCompleteColLabel").removeAttribute("sortDirection");        
  6719.         document.getElementById("todoShowInTooltip").removeAttribute("sortDirection");        
  6720.         document.getElementById("todoTimeColLabel").removeAttribute("sortDirection");        
  6721.         document.getElementById("todoAlarmColLabel").removeAttribute("sortDirection");        
  6722.         document.getElementById("todoNotesColLabel").removeAttribute("sortDirection");        
  6723.         document.getElementById("todoMailColLabel").removeAttribute("sortDirection");                    
  6724.         document.getElementById("todocatColLabel").removeAttribute("sortDirection");
  6725.         document.getElementById("todoEndDateColLabel").removeAttribute("sortDirection");                
  6726.     }
  6727.  
  6728.  }
  6729.  
  6730.  
  6731. function sortTodoIfNeccessary(todoID) {
  6732.     if ( isTabSorted() ) {
  6733.         removeAllListItems( false, true );
  6734.         fillList( false, true);            
  6735.     }          
  6736.     
  6737.     
  6738.     var todoName;
  6739.     var tabList = document.getElementById("tabList");    
  6740.     var tab =    tabList.selectedItem;
  6741.     var tabIndex =    tabList.selectedIndex;
  6742.     var index = tab.id.indexOf( ':' );
  6743.     if ( tabIndex <= 1 || index == -1 ) {
  6744.         todoName = REMINDER_FOX_DEFAULT_TODOS_CATEGORY;
  6745.     }
  6746.     else {
  6747.         todoName = tab.id.substring( index +1 , tab.id.length );
  6748.     }
  6749.     selectTodoById(todoName, todoID );
  6750. }
  6751.  
  6752. function sortReminderIfNeccessary(reminderID) {
  6753.     if ( isTabSorted() ) {
  6754.         removeAllListItems( true, false );
  6755.         calendarReminderArray = null;
  6756.         fillList( true, false);            
  6757.         selectReminderById(reminderID);
  6758.     }              
  6759. }
  6760.  
  6761. function displayTypeChanged(event) {
  6762.     calendarReminderArray = null;  // null out in case reminder columns are sorted
  6763.     refillLists();  
  6764. }
  6765.  
  6766. function displayTypeChangedTodo(event) {
  6767.     calendarTodoArray = null;
  6768.     refillLists(); 
  6769. }
  6770.  
  6771. function getDisplayIndex() {
  6772.     var displayList;
  6773.     var displayListIndex = -1;
  6774.     if ( isReminderTabSelected() ) { 
  6775.         displayList = document.getElementById("displayType");
  6776.     }
  6777.     else {
  6778.         displayList = document.getElementById("displayTypeTodo");
  6779.     }    
  6780.     if ( displayList != null ) {    
  6781.         displayListIndex = displayList.selectedIndex;
  6782.     }
  6783.     return displayListIndex;
  6784. }
  6785.